Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
 Refresh & Autoincrement with SQL-сервер  [new]
apapacy
Member

Откуда:
Сообщений: 1297
При работе с сервером из Фокса 6.0 в свое время столкнулся с двумя проблемами которые так и не решил. Сейчас как понимаю в 9 возможностей поболее.
1) После получения курсора с сервера он не не обновляется автоматически (как при работе с дбф) данными измененными другими пользователями. Как я понимаю в новых версиях Фокса Refresh() вызывает CursorAdapter.RecordRefresh() должен решить проблему для записей в текущем наборе. А как быть с новыми (добавленными) записями?
2) Аналогично с полями autoincrement. Если я вставляю null то сервер генерирует autoincrement. По сути у меня втавилась запись но я не могу к ней обратиться так как не знаю какой там у нее ключ, т.к. в локальном наборе у меня по-прежнему null. (собственно решил в свое время отказом от встроенніх механизмов autoincrement на сервере и переносом на клиент)
1 июл 13, 08:16    [14503035]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
Станислав С...кий
Guest
apapacy,
У нас это все решено через представления (view): одно для просмотра (много записей, не редактируемое), другое для редактирования (одна запись, изменения согласуются с сервером).
При обновлении формы делаешь перезапрос данных "просмотрового" представления.
При окончании процедуры редактирования представление для редактирования согласует свои данные с сервером в момент вызова tableupdate(). Тогда же и получаем код, назначенный полю с автоинкрементом.
1 июл 13, 08:31    [14503068]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
apapacy
При работе с сервером из Фокса 6.0 в свое время столкнулся с двумя проблемами которые так и не решил. Сейчас как понимаю в 9 возможностей поболее.
1) После получения курсора с сервера он не не обновляется автоматически (как при работе с дбф) данными измененными другими пользователями. Как я понимаю в новых версиях Фокса Refresh() вызывает CursorAdapter.RecordRefresh() должен решить проблему для записей в текущем наборе. А как быть с новыми (добавленными) записями?
2) Аналогично с полями autoincrement. Если я вставляю null то сервер генерирует autoincrement. По сути у меня втавилась запись но я не могу к ней обратиться так как не знаю какой там у нее ключ, т.к. в локальном наборе у меня по-прежнему null. (собственно решил в свое время отказом от встроенніх механизмов autoincrement на сервере и переносом на клиент)


1. Начиная с VFP 3, Remote View обновлялось ф-ией Requery()

2. Для сохранения используйте ХП сервера из которой передавайте ID записи (SCOPE_IDENTITY() )
1 июл 13, 09:56    [14503431]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
apapacy
Member

Откуда:
Сообщений: 1297
Согласитесь, что Requery() - со всеми сопутсвующими - сбросом позиции скроллинга, зависанием на момент запроса интерфейса, мерцанием грида - это далеко не то о чем может мечтать по крайней мере пользователь.
1 июл 13, 10:26    [14503585]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
apapacy
Member

Откуда:
Сообщений: 1297
SCOPE_IDENTITY() предполагает MSSQL-сервер.
Для него есть решение и попроще - я сам это рыл лет 5 назад. Но CursorAdapter c 7 or 8 Фоксом точно не вспомню - сам обновлял автоинкрементные поля. Речь идет об общем случае (любой сервер не МС)
1 июл 13, 10:30    [14503617]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
apapacy
Согласитесь, что Requery() - со всеми сопутсвующими - сбросом позиции скроллинга, зависанием на момент запроса интерфейса, мерцанием грида - это далеко не то о чем может мечтать по крайней мере пользователь.



1 Ну, а просто запомнить ID до Requery(), а затем поиск по нему на клиенте... либо в случае новой записи, получение ID и поиск по нему.

2. А сколько записей на ваш взгляд должно обновляться по Requery() одна или же все удовлетворяющие критерию выборки ?

3. Form.LockScreen устраняет мерцание грида.


apapacy
SCOPE_IDENTITY() предполагает MSSQL-сервер.
Для него есть решение и попроще - я сам это рыл лет 5 назад. Но CursorAdapter c 7 or 8 Фоксом точно не вспомню - сам обновлял автоинкрементные поля. Речь идет об общем случае (любой сервер не МС)


4. Если вы обратили внимание, то я предложил общее решение через ХП, а SCOPE_IDENTITY() указал в скобках.

5. CursorAdapter появился в 8-ой версии.

PS
1 июл 13, 11:09    [14503837]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
12345зайчик
Guest
для 9-ки
я дописывал методы КАД
побежать по записям,
если записи новые и ключик уникальный неприсвоен, то генерим новый уник.ключ на станции и проваливаем и сохраняем
всю строку со всеми значениями на серевер

....
				* Обновление каскадов
				* Обновляем последовательно все измененные записи в курсоре
				do while !empty(lnUpdatedRecn)
					go (lnUpdatedRecn) in .alias
					if !.updateRecord(@laErrors)
					    llSuccess = .f.
					    Exit
					endif
					lnUpdatedRecn = .getModified(lnUpdatedRecn)
					if empty(lnUpdatedRecn)
						exit
					endif
				enddo
....


в методе до обновления записи, присваивал значение идентификатору
with this
	if empty(.getKeyValue()) and .typeKeyField ="C"
		replace (.KeyFieldList) with newId() in (.Alias)
	endif
endwith
1 июл 13, 11:36    [14503996]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
12345зайчик
Guest
вышепредставл. код для uniqueidentifier


для автоинкр-та поступал так:

with this
	if !.beforeUpdateRecord()
		return .f.
	endif
	* Определяем факт добавления записи
	local llNewRec, llDelRec, lcFldState, laErrors[1], luCurrentIdValue
	lcFldState = .getfldstate()
	llNewRec   = "3"$lcFldState or "4"$lcFldState
	llDelRec   = deleted(.Alias)
	if llNewRec and  !.beforeUpdateNewRecord()
		return .f.
	endif
	* Обновляем данные для записи	
	if tableupdate(.f., !empty(.nForceUpdate), .alias)
		if llNewRec and !llDelRec 
			If  !.afterUpdateNewRecord()
				return .f.
			EndIf
			* заменяем ключь в каскаде на новое значение
			If !.lLockTransactions 
				.oCadCascad.CheckIsTransactable()
			EndIf 
			luCurrentIdValue = .uCurrentIdValue
			Text to lcCmd NOSHOW TEXTMERGE PRETEXT 15
				Update <<.oCadCascad.alias>> set .KeyFieldList = <<luCurrentIdValue>> 
					where .KeyFieldList<><<luCurrentIdValue>>
			EndText
			&lcCmd
			* сохраняем записи в каскаде			
			If !.oCadCascad.saveCursor(.t.) && лочим сообщения об ошибках
				.cError = .oCadCascad.cError
				Return .f.
			EndIf
		endif
	else


дерг значения ключа взад в методе afterUpdateNewRecord
для with this

	if !empty(.keyFieldList) ;
	   and empty(.InsertCmdRefreshKeyFieldList) ;
	   and empty(.getKeyValue()) and .typeKeyField ="N" 
		
		Local lcSqlCmd
		Text to lcSqlCmd NOSHOW TEXTMERGE PRETEXT 15
			select id=IDENT_CURRENT('[<<.tables>>]')
		EndText
		If oServer.sqlexec( lcSqlCmd, "tmp_lastId", set("Datasession"))>0
			replace (.keyFieldList) with tmp_lastId.id in (.Alias)
			use in select("tmp_lastId")
		EndIf
			  
	EndIf
	
endwith
1 июл 13, 11:49    [14504111]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
ВладимирМ
Member

Откуда: г. Москва
Сообщений: 7864
apapacy
При работе с сервером из Фокса 6.0 в свое время столкнулся с двумя проблемами которые так и не решил. Сейчас как понимаю в 9 возможностей поболее.
1) После получения курсора с сервера он не не обновляется автоматически (как при работе с дбф) данными измененными другими пользователями. Как я понимаю в новых версиях Фокса Refresh() вызывает CursorAdapter.RecordRefresh() должен решить проблему для записей в текущем наборе. А как быть с новыми (добавленными) записями?

Практическая потребность видеть данные, измененные другим пользователем в режиме on-line - крайне незначительная. Более того, как правило, даже если Вы реализуете такой механизм, то, скорее всего, Вас попросят его отключить. Вот Вам бы понравилось, если, например, Вы печатаете некий текст, а предыдущий абзац кто-то изменил или удали? Вот прямо пока Вы вводите следующий абзац!

Обновление данных, конечно, выполняется. Но именно что перезапросами. Полными, а не отдельной записи. Но поскольку это обновление выполняется не on-line, а связывается с некими действиями самого пользователя (сохранение, возврат к списку, поиск и т.п.), то это происходит незаметно для самого пользователя.

Разумеется, могут быть и задачи on-line обновления. Но, как правило, подобные задачи сами по себе крайне специфичны. Обычно решают задачу мониторинга, а вовсе не изменения данных

apapacy
2) Аналогично с полями autoincrement. Если я вставляю null то сервер генерирует autoincrement. По сути у меня втавилась запись но я не могу к ней обратиться так как не знаю какой там у нее ключ, т.к. в локальном наборе у меня по-прежнему null. (собственно решил в свое время отказом от встроенніх механизмов autoincrement на сервере и переносом на клиент)

Это вовсе не "аналогично". Это принципиально другая задача. Работа с автоинкрементыми полями требует понимания того, а что это такое. Для работы с ними нужно по другому строить саму логику работы с данными. Принципиально не так, как с DBF.

Как прочитать значение поля со свойством IDENTITY

Собственно, идеальный режим работы с автоинкрементными полями от MS SQL - это создание/изменение по одной записи за раз. Разумеется, речь идет об интерактивном изменении данных. Пользователем на формах. Программная модификация - это другое. Но большинство программистов просто не способны "переключить мозги". Подобный режим работы кажется им чем-то противоестественным.
1 июл 13, 21:19    [14507320]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
apapacy
Member

Откуда:
Сообщений: 1297
Я могу привести пример, когда онлайн обновление будет полезно.
Например идет речь о списке товаров, который может обонвляется товароведом в течение дня и в форме (скажем кассира или кладовщика) вводиотся через комбобокс.
Волне естественно, что список товаров достаточно большой для постоянного рефреша при открытии формы ввода.

Например сейчас, отойдя от Фокса я делаю это достаточно просто. На сервере запрашиваются ровно столько записей (скажем 10) сколько отображены в аналоге комбобокса по первым введенным буквам. И реализовано листание (если данных больше чем можно отобразить за раз) Естественно что данные всегда актуальны.

В Фоксе я для комбобокса запрашиваю всю таблицу. Конечно можно поступать аналогично и запрашивать по первым введенным буквам. Но тогда по первой букве (скажем я ввел только одну) все равно будет запрошено много данных.
Конечно можно организовать "листание" как я и делаю сейчас не в Фоксе. Но как мне кажется на Фоксе это будет не слишком удобно в реализации. Или есть предложения получше?
1 июл 13, 21:45    [14507395]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
apapacy
Я могу привести пример, когда онлайн обновление будет полезно.
...
Естественно что данные всегда актуальны.


1. Конечно есть задачи где необходимо on-line обновление, классический пример - кассы продажи билетов на поезд.

2. Как только клиент получил данне с сервера, то данные стали устаревшими - это иллюзия, что чем чаще обновляются данные на клиенте тем актуальность данных выше.

apapacy
В Фоксе я для комбобокса запрашиваю всю таблицу. Конечно можно поступать аналогично и запрашивать по первым введенным буквам. Но тогда по первой букве (скажем я ввел только одну) все равно будет запрошено много данных.
Конечно можно организовать "листание" как я и делаю сейчас не в Фоксе. Но как мне кажется на Фоксе это будет не слишком удобно в реализации. Или есть предложения получше?


3. Не фоксе тоже надо запрашивать необходимое кол-во, вы же понимаете, что если отбор реализован на сервере, то любой клиент может получить урезанную выборку.

4. Обычно (при больших справочниках не используют интерактивный поиск), используют поиск по Enter, предполагается, что юзер осознано ввёл Enter, что бы получить ограниченную выборку.
2 июл 13, 09:20    [14508151]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
apapacy
Member

Откуда:
Сообщений: 1297
В общем-то все так. Но вот 1с 7.7 которую принято ругать, при работе с MS-SQLServer все справочники, документы и списки для выбора тихо обновляются при необходимости (и что характерно без "дрожжания" экрана как у того же фокса в ДБФ версии при авто-обновлении BROWSE по таймеру). Хотелось бы такого функционала встроенного в систему.

Аналогично ведет себя и MS-Access в связке с MSSQL.

Видимо надо будет попробовать сваять програмно на Фоксе хотя бы для комбобокса.
2 июл 13, 11:30    [14509238]     Ответить | Цитировать Сообщить модератору
 Re: Refresh & Autoincrement with SQL-сервер  [new]
PaulWist
Member

Откуда:
Сообщений: 2236
apapacy
В общем-то все так. Но вот 1с 7.7 которую принято ругать, при работе с MS-SQLServer все справочники, документы и списки для выбора тихо обновляются при необходимости (и что характерно без "дрожжания" экрана как у того же фокса в ДБФ версии при авто-обновлении BROWSE по таймеру). Хотелось бы такого функционала встроенного в систему.

Аналогично ведет себя и MS-Access в связке с MSSQL.

Видимо надо будет попробовать сваять програмно на Фоксе хотя бы для комбобокса.


1. Дык, кто запрещает использовать асинхронные вызовы, ... качни 10 записей, и пока юзер чешет репу, докачай ещё 100...100500, для конкретного интерфейса выбирается конкретное исполнение.

2. Попробуйте в 1С-справочник закачать 100-200 тыс записей и посмотрите на быстродейчтвие 1С, будете очень удивлены.
2 июл 13, 11:43    [14509353]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить