for flooders
:: Главная :: Решения :: Статьи :: Сайт М. Дроздова :: Файловый архив :: Книга по VFP 9 :: Русский Help Online :: OFF-LINE Форум
   Лисоводы   всех   стран,  объединяйтесь !!!  

Список Форумов  :: Visual Foxpro, Foxpro for DOS
  

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 13130
Дата: 07.04.06 14:30:46
Ну да те же яйца только в профиль.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Влад Колосов

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата: 07.04.06 14:35:34
Я уж не стал об этом писать


------------------
Совершенство - это не тогда, когда нельзя
ничего прибавить, а тогда, когда нечего убавить.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 13130
Дата: 07.04.06 14:43:08
Ну такой примерно алгоритм 1.5 года назад рассказывал для Aijik-a forum.foxclub.ru


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Вячеслав Клепинин
Автор

Сообщений: 1597
Откуда: Санкт-Петербург
Дата: 07.04.06 15:35:17
Ну, мужики, вы даёте... Нехорошо стебаться.
Паша, внимательно просмотрел твою ссылку. Ессно, что когда я искал инфу в поисковике, это не было найдено. Да, там есть пример пакетного обновления представлений. Но мой вопрос совсем о другом: это использование курсор адаптера, обработка его событий и получение от сервера значения ключа, объявленного как IDENTITY, в событии курсор адаптера. Есдинственное, что я нашёл - это коды, предложенные Алекссем Цингаузом (здесь на эти материалы ссылается Владимир Максимов), где используется глобальная переменная INENTITY. То решение, которое я опубликовал, возможно, не самое лучшее. Но время идёт, и проект делать нужно, а я потратил на поиск решения целый день.

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



Исправлено: Вячеслав Клепинин, 07.04.06 15:36
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 13130
Дата: 07.04.06 15:48:03
Вячеслав.

Да нет красивого решения, все они через известное место, так что никто не смеётся, просто констатация факта. А твоё желание понятно, если используешь CA, то хотелось бы иметь полный функционал, а то шаг-влево - шаг в право - надо использовать подпорки. Так что нашел своё решение и хорошо.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Влад Колосов

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата: 07.04.06 15:58:32
То-то и оно, что с этим identity нет очевидных решений.
Более всего лично мне нравится вариант со вставкой SQLEXEC() и requery(),
который и использую в последнее время.
Но как он себя поведет на больших таблицах - не знаю.


------------------
Совершенство - это не тогда, когда нельзя
ничего прибавить, а тогда, когда нечего убавить.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 13130
Дата: 07.04.06 16:20:35
Цитата:
Более всего лично мне нравится вариант со вставкой SQLEXEC() и requery(),

requery чего?


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Влад Колосов

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата: 07.04.06 16:45:56
SQL View.


------------------
Совершенство - это не тогда, когда нельзя
ничего прибавить, а тогда, когда нечего убавить.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 13130
Дата: 07.04.06 17:00:31
Влад Колосов
SQL View.

А как ты тогда выясняешь - добавленная запись попала в критерий выборки View?


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Влад Колосов

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата: 07.04.06 17:09:55
Хм... Пока что не было необходимости это проверять для тех случаев, когда используется
SQLEXEC() и REQUERY(). Выбираются все записи.


------------------
Совершенство - это не тогда, когда нельзя
ничего прибавить, а тогда, когда нечего убавить.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Владимир Максимов

Сообщений: 13843
Откуда: Москва
Дата: 07.04.06 23:19:15
Вячеслав Клепинин
Но мой вопрос совсем о другом: это использование курсор адаптера, обработка его событий и получение от сервера значения ключа, объявленного как IDENTITY, в событии курсор адаптера. Есдинственное, что я нашёл - это коды, предложенные Алекссем Цингаузом (здесь на эти материалы ссылается Владимир Максимов), где используется глобальная переменная INENTITY.
Вячеслав, Вы невнимательно прочитали тот топик. Там предложено 3 решения.

1) Поиск новой записи по значению других полей. Не ключевых, но тоже уникальных.

Например, если речь идет о справочнике, то Identity - это внутренний код, который пользователь не видит. Но пользователь видит название элемента справочника. Это поле также является уникальным, иначе в справочнике просто нет смысла. Зачем вводить 2 одинаковых названия?

В версии VFP9 операция поиска новой записи по дополнительным полям автоматизирована при помощи дополнительных настроек CursorAdapter

InsertCmdRefreshFieldList - список полей, значение которых будет обновлено после Insert
InsertCmdRefreshKeyFieldList - поле, или набор НЕ ключевых полей также однозначно идентифицирующих запись

Более подробно это описано здесь

CursorAdapter: Авто-рефреш полей во время TABLEUPDATE

2) Чтение значения системной переменной @@IDENTITY после операции вставки.

Это просто в событии AfterInsert делается запрос через SQLExec() на сервер по номеру того же соединения в котором работает CursOrAdapter.


3) Подмена стандартной команды на вставку вызовом собственной хранимой процедуры.

Это похоже на Ваше решение, но реализовано несколько по другому.

На сервере создается временная хранимая процедура примерно такого вида

  
  CREATE procedure #CategoryIns   
  	@id int OUTPUT,   
  	@Name varchar(15),     
    	@Descr text    
  AS    
    
  INSERT into Categories (CategoryName,Description) VALUES (@Name, @Descr)    
  SELECT @id=SCOPE_IDENTITY()

Затем подменяется стандартная команда создания новой записи (корректируется свойство InsertCmd) примерно такой.

InsertCmd="EXEC #CategoryIns ?@CACategories.Id OUTPUT, ?CACategories.Name, ?CACategories.Descr"

Плюс настройка

InsertCmdRefreshFieldList = "id"

Чтобы поле было обновлено после вставки

Собственно, все. При вставке новой записи будет выполнена ХП сервера и в поле таблицы CACategories.Id будет возвращено значение SCOPE_IDENTITY()
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Aleksey Tsingauz [MSFT]

Сообщений: 407
Дата: 09.04.06 06:38:32
Вячеслав Клепинин
Эти материалы Цингауза я читал, именно там и нашёл решение.
Единственное, я не пользовал в своём коде TABLEUPDATE(.F.) - как у него, почему-то считал, что курсор адаптер сам всё сделает. Тем более, что инструкция INSERT ... SELECT ... отрабатывает нормально, без явного вызова TABLEUPDATE(). С TABLEUPDATE() всё работает правильно.

Здравствуйте, Вячеслав!

Если CursorAdapter правильно настроен, то он сам все сделает. Только, без явного или неявного TABLEUPDATE(), извлекать с сервера нечего. Новое значение IDENTITY будет сгенерировано сервером только когда будет сделана попытка добавления новой записи на сервере, а этим занимается TABLEUPDATE(). Так же, если вы внимательно прочитаете документацию, событие AfterInsert и другие подобные события не должны срабатывать во время модификации курсора, а должны срабатывать во время модификации данных на сервере, т.е. во время TABLEUPDATE(). Если используется row buffering, перемещение с модифицированной записи вызыват неявный TABLEUPDATE(), что объясняет почему Grid отображает новое значение. Перемещение в Grid-е на другую запись вызывает добавление новой записи на сервере и CursorAdapter, как и положено, извлекает новое значение IDENTITY.

[SELECT SCOPE_IDENTITY() AS newID] не срабатывает в AfterInsert в связи со спецификой работы ODBC драйвера для SQL Server-а. Если у команды есть параметры, то Sql Server ODBC драйвер выполняет ее, используя процедуру sp_executesql. Т.е. команда выполняется внутри sp_executesql и scope/контекст для неё будет эта процедура. Последующее выполнение [SELECT SCOPE_IDENTITY() AS newID] просто выполняется в другом контексте и "не видит" значений сгенерированных внутри sp_executesql.

Алексей.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Aleksey Tsingauz [MSFT]

Сообщений: 407
Дата: 09.04.06 07:19:49
boba
я возился сэтим делом пару месяцев и более
половина событий срабатывает один раз всего
если только нет в коде пары tableupdate- cursorfill ( те перезапрос)
Как я помню такая же штука раньше была в ремоут вью
Второй tableupdate давал правду, но на деле извменений н6е вносил
А работало так tableupdate -requery()
Как я понял, класс курсор адаптера собран из механизма view
и работает по этому сценарию
а иначе не работает не только упомянутое вами событие но и куча других
Я тоже вел переписку с Микрософт по этому поводу , конкретно с Джимом Сандерсом , они подтвердили все это
Може исправят во втором сервис пэке так как уже много людей обратило на это внимание

Здравствуйте, Владимир!

Прошу прощения, но все выше сказанное вами слишком запутано. Насколько мне известно, на текущий момент у нас нет ни одного активного бага на работу TABLEUPDATE для VIEW и CursorAdapter, также нет ни одного активного бага на работу событий CursorAdapter-а.

Поэтому
1) Нет никаких планов что-либо исправлять в этой области.
2) Джим просто не мог подтвердить вам, что "не работает не только упомянутое вами событие но и куча других" и что "уже много людей обратило на это внимание".

Я допускаю, что вы просто не поняли друг друга.

Если поблемы действительно есть, то давайте их здесь разберем. Я буду признателен если вы сможете четко и ясно описать каждую из проблем и привести демонстрирующий код. Со своей стороны, я обещаю приложить все старания для того, чтобы проблемы были исправлены в SP2.

С уважением,
Алексей.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Владимир Максимов

Сообщений: 13843
Откуда: Москва
Дата: 10.04.06 01:56:18
Поскольку обсуждение данной проблемы появляется снова и снова, то наборосал небольшую статью. Стоит ли ее разместить в статьях (может, чего подправить) или выбросить все лишнее и сделать небольшую заметку в FAQ?
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Aleksey Tsingauz [MSFT]

Сообщений: 407
Дата: 10.04.06 04:54:45
Вячеслав Клепинин
Всё оказалось достаточно просто. Нужно при помощи SQLEXEC добавлять запись непосредственно в таблицу на сервере, одновременно получая значение SCOPE_IDENTITY(), потом обновлять курсор и позиционироваться на запись с полученным ID:

Вячеслав,

Возможно способ описанный здесь forum.foxclub.ru покажется вам проще, достаточно вызвать TABLEUPDATE() для записи и значение будет извлечено.

Алексей.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Aleksey Tsingauz [MSFT]

Сообщений: 407
Дата: 10.04.06 05:08:45
Владимир Максимов
Поскольку обсуждение данной проблемы появляется снова и снова, то наборосал небольшую статью. Стоит ли ее разместить в статьях (может, чего подправить) или выбросить все лишнее и сделать небольшую заметку в FAQ?

Здравствуйте, Владимир!

Я поместил еще один способ для CursorAdapter-а и SCOPE_IDENTITY() - forum.foxclub.ru.

Так же, помимо использования AfterInsert, значение @@IDENTITY можно извлечь с помощью InsertCmdRefreshCmd.
  
  CA.InsertCmdRefreshCmd = "SELECT @@IDENTITY"
или
  
  CA.InsertCmdRefreshCmd = "SELECT ...  Where ID = @@IDENTITY"

Алексей.
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 13130
Дата: 10.04.06 10:59:30
Цитата:
(может, чего подправить) или выбросить все лишнее и сделать небольшую заметку в FAQ?

По сути вопроса, лишнего нет - выбрасывать нечего , думаю в FAQ-е надо привести варианты и код получения нового значения, а так же сделать ссылку на статью, где будет описана сама теория.

Ещё, замечание, надо как-то выделить, что речь идет в рассматриваемых примерах о "сбросе" одной и только записи для получения её IDENTITY, иначе возникает неоднозначность.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)




Исправлено: PaulWist, 10.04.06 10:59
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 13130
Дата: 11.04.06 10:09:45
Владимир, ещё надо бы в статье сказать о правах на создаваемую временную ХП, что не всё так просто


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
boba

Сообщений: 5391
Откуда: Медвежьи озера-
Дата: 17.04.06 11:28:22
Алексей, я действительно написал несколько путано
Я не считал это багом и как баг не описывал. Но эта ситуация действительно несколько раз всплывала на UT
Я написал тут 1=1 то же самое , что и вы , только действительно путано
А именно, события адаптера срабатывают на события на сервере. те пока не выдашь tableupdate нет и события Интуитивно многие ожидают другого поведения, реакции на изменения курсора на клиенте, отсюда и недоразумение

Еще я писал про другую вещь, которая долгое время была в remote view
Наверное не стоило это писть в одном посте
А было там вот что, делаешь requery() на remoteview()
Делаешь в курсоре изменения
Пишешь m.ok, и на сервере изменения есть
Делаешь на клиенте в курорсоре снова изменения и снова пишешь tableupdate
Он снова возвращает правду, но изменения на сервер уже не заносятся
Если до второго изменения и tableupdate вызывать requery то все ок
Я пороюсь в своих учебных примерах
Ratings: 0 negative/0 positive



Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 20 Taran Ytuzov Simple777  (Гостей: 17)

20.06.2019 23:13:04 exec: 0.22
Mem: 1.45 Mb

© 2000-2019 Fox Club 
Яндекс.Метрика