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

Сообщений: 14618
Дата регистрации: 01.04.2004
Ну да те же яйца только в профиль.


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

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата регистрации: 05.05.2005
Я уж не стал об этом писать


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

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


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Вячеслав Клепинин
Автор

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

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



Исправлено 2 раз(а). Последнее : Вячеслав Клепинин, 07.04.06 15:36
Ratings: 0 negative/0 positive
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Вячеслав.

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


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

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


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

Сообщений: 14618
Дата регистрации: 01.04.2004
Цитата:
Более всего лично мне нравится вариант со вставкой SQLEXEC() и requery(),

requery чего?


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

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата регистрации: 05.05.2005
SQL View.


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

Сообщений: 14618
Дата регистрации: 01.04.2004
Влад Колосов
SQL View.

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


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

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


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

Сообщений: 14098
Откуда: Москва
Дата регистрации: 02.09.2000
Вячеслав Клепинин
Но мой вопрос совсем о другом: это использование курсор адаптера, обработка его событий и получение от сервера значения ключа, объявленного как 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
Дата регистрации: 15.06.2004
Вячеслав Клепинин
Эти материалы Цингауза я читал, именно там и нашёл решение.
Единственное, я не пользовал в своём коде 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
Дата регистрации: 15.06.2004
boba
я возился сэтим делом пару месяцев и более
половина событий срабатывает один раз всего
если только нет в коде пары tableupdate- cursorfill ( те перезапрос)
Как я помню такая же штука раньше была в ремоут вью
Второй tableupdate давал правду, но на деле извменений н6е вносил
А работало так tableupdate -requery()
Как я понял, класс курсор адаптера собран из механизма view
и работает по этому сценарию
а иначе не работает не только упомянутое вами событие но и куча других
Я тоже вел переписку с Микрософт по этому поводу , конкретно с Джимом Сандерсом , они подтвердили все это
Може исправят во втором сервис пэке так как уже много людей обратило на это внимание

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

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

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

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

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

С уважением,
Алексей.
Ratings: 0 negative/0 positive
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Владимир Максимов

Сообщений: 14098
Откуда: Москва
Дата регистрации: 02.09.2000
Поскольку обсуждение данной проблемы появляется снова и снова, то наборосал небольшую статью. Стоит ли ее разместить в статьях (может, чего подправить) или выбросить все лишнее и сделать небольшую заметку в FAQ?
Ratings: 0 negative/0 positive
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Aleksey Tsingauz [MSFT]

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

Вячеслав,

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

Алексей.
Ratings: 0 negative/0 positive
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
Aleksey Tsingauz [MSFT]

Сообщений: 407
Дата регистрации: 15.06.2004
Владимир Максимов
Поскольку обсуждение данной проблемы появляется снова и снова, то наборосал небольшую статью. Стоит ли ее разместить в статьях (может, чего подправить) или выбросить все лишнее и сделать небольшую заметку в 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

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

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

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


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




Исправлено 1 раз(а). Последнее : PaulWist, 10.04.06 10:59
Ratings: 0 negative/0 positive
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
Владимир, ещё надо бы в статье сказать о правах на создаваемую временную ХП, что не всё так просто


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

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

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


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

On-line: 25 (Гостей: 25)

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