CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Вячеслав Клепинин Автор Сообщений: 1597 Откуда: Санкт-Петербург Дата регистрации: 26.03.2004 |
Привет всем!
В методе Load формы создаю объект из класса MyCursorAdapter:
Поле id_tk в таблице tk на MS SQL Server - типа IDENTITY. Надо получать его значение после вставки очередной записи. Для этого в классе MyCursorAdapter, наследуемом от CursorAdapter, в обработчике AfterInsert пишу:
На форме Grid, в котором отображается курсор. Код в Click кнопки, по которой добавляется новая запись:
Вызываемая форма InputString просто позволяет ввести строку и возвращает её в Unload'e. После добавления новой записи она появляется в Grid, но вижу, что значение поля id_tk равно нулю. Событие AfterInsert курсорадаптера происходит только после перемещения указателя в курсоре на соседнюю (или любую другую) запись, после чего сразу вижу, что поле id_tk добавленной записи становится отличным от нуля и соответстует значению этого поля в таблице на сервере. Меняю код в методе Click кнопки:
Делаю так:
Почему-то такой вариант работает. И ещё. В методе AfterInsert пытаюсь получить значение функции SCOPE_IDENTITY():
Вот такая, блин, загогулина. Господа, просветите! Заранее спасибо! |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
BOL
Returns the last IDENTITY value inserted into an IDENTITY column in the same scope. A scope is a module -- a stored procedure, trigger, function, or batch Поскольку в SQLEXEC(this.DataSource, "SELECT SCOPE_IDENTITY() AS newID", "_cur_id") НЕ производится вставка, то и SCOPE_IDENTITY() возвращает null. P.S. Я бы делал SendUpdates после вставки, CA все же буферизирован. ------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. Исправлено 1 раз(а). Последнее : Влад Колосов, 06.04.06 17:09 |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Владимир Максимов Сообщений: 14098 Откуда: Москва Дата регистрации: 02.09.2000 |
|
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
PaulWist Сообщений: 14618 Дата регистрации: 01.04.2004 |
Мда, нет решения.
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Владимир Максимов Сообщений: 14098 Откуда: Москва Дата регистрации: 02.09.2000 |
Почему? По приведенной ссылке 3 варианта решения. Два действуют при некоторых ограничениях, а через хранимые процедуры работает всегда. |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
PaulWist Сообщений: 14618 Дата регистрации: 01.04.2004 |
Владимир, да всё это, на мой взгляд, через "назад", приведенные Цингаузом решения приходилось использовать и раньше.
Хотя, зависит от задачи, но возвращать IDENTITY на клиета опять же на мой взгляд не совсем правильно, всё таки это нарушает логику КС, подозреваю, что IDENTITY на клиенте в большинстве случаев нужен для заполнения FK, что как сам понимаешь - не правильно. ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Владимир Максимов Сообщений: 14098 Откуда: Москва Дата регистрации: 02.09.2000 |
Почему? А как же создавать документы имеющие "шапку" и "детали"? Т.е. создали запись в шапке и ... как создать детали не зная кода в только что созданной шапке? |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Вячеслав Клепинин Автор Сообщений: 1597 Откуда: Санкт-Петербург Дата регистрации: 26.03.2004 |
Владимир Максимов
Эти материалы Цингауза я читал, именно там и нашёл решение. Единственное, я не пользовал в своём коде TABLEUPDATE(.F.) - как у него, почему-то считал, что курсор адаптер сам всё сделает. Тем более, что инструкция INSERT ... SELECT ... отрабатывает нормально, без явного вызова TABLEUPDATE(). С TABLEUPDATE() всё работает правильно. Влад Колосов > Поскольку в SQLEXEC(this.DataSource, "SELECT SCOPE_IDENTITY() AS newID", "_cur_id") > НЕ производится вставка, то и > SCOPE_IDENTITY() возвращает null. Обойти это никак нельзя? Планируется многопользовательский ввод, боюсь, что с @@IDENTITY будут проблемы. Исправлено 1 раз(а). Последнее : Вячеслав Клепинин, 06.04.06 18:37 |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Вячеслав Клепинин Автор Сообщений: 1597 Откуда: Санкт-Петербург Дата регистрации: 26.03.2004 |
PaulWist
Цитата:В том - то и дело, идёт оперативный ввод рекламных модулей, порядка 2000 в день, и если в базе нет какого-то сопуствующего параметра, например, организации или классификатора, их нужно оперативно добавлять при вводе модуля. То есть добавили организацию, и сразу в несколько таблиц ставим её id. |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Владимир Максимов Сообщений: 14098 Откуда: Москва Дата регистрации: 02.09.2000 |
Так там же по ссылке и приведено решение - хранимые процедуры. По другому SCOPE_IDENTITY() для CursorAdapter - не получишь, поскольку происходит выполнение другого SCOPE. Вне контекста CursorAdapter. |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
PaulWist Сообщений: 14618 Дата регистрации: 01.04.2004 |
Ну как, - создаём временную табличку на сервере (или используем готовую постоянную-временную табличку) засылаем на сервер запись из мастера - засылаем Детали - вызываем ХП, которая знает о наших временных табличках и умеет эти данные засунуть в постоянные таблички В данном случае нет головной боли о возврате для IDENTITY, те если надо ХП через OUTPUT вернёт ID, и тогда можно сделать REQUERY() и то только в том случае если занесенная запись удовлетворяет критерию отбора. ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
PaulWist Сообщений: 14618 Дата регистрации: 01.04.2004 |
Вячеслав, надо ли это понимать, что в форме ввода есть возможность добавлять новые позиции в справочник? Те вызывается форма редактирования справочника из модуля редактирования документа? Если это так, то вполне оправдвнный подход, только через CA решение двухступенчатое, не порще ли использовать ХП. ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Владимир Максимов Сообщений: 14098 Откуда: Москва Дата регистрации: 02.09.2000 |
Это надо понимать так, что от Cursor Adapter следует отказаться? Как стыкуется идеология временных таблиц и уже сделанная выборка? Или же предполагается перхватывать момент сброса изменений и писать собственную ХП (создание временных таблиц, закачка данных, вызов ХП)? И чем этот подход отличается от подхода описанного Алексеем по поводу создания собственной ХП для возврата SCOPE_IDENT()? Как мне кажется, у Алексея все значительно проще. |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
PaulWist Сообщений: 14618 Дата регистрации: 01.04.2004 |
Цитата: Да, надо отказаться. Аргумент один и не бесспорный - придерживаться одной выбранной идеологии, во всяком случае для меня, не надо вспоминать "а вот в этой форме" как осуществляется работа с данными. Цитата: Вопрос давольно большой. Добавление данных Мастер-Детали (курсоры на клиенте "пустые" в смысле не выбраны с сервера, заполнены пользователем) Идея.
Для модификации существующей выборки принцип такой же, только осложненный проверками, замечу проверками на сервере, а не на клиенте Цитата: Ну вроде предыдущий пример даёт ответ на вопрос методологии, насчёт проще или нет трудно сказать, мне кажется при изложенном подходе, клиент выполняет роль "отправщика" данных на сервер, а в ответ получает только результат успеха-не успеха модификации. Логика приложения (бизнес логика если угодно) сосредоточина на сервере, а не размазана по приложению, клиент в данном случае вроде не причём. ------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Вячеслав Клепинин Автор Сообщений: 1597 Откуда: Санкт-Петербург Дата регистрации: 26.03.2004 |
PaulWist
Цитата: Да, именно так. Сущность "Модули", ессно, включает в себя мигрирующие ключи, но, кроме этого, она связана с несколькими другими сущностями отношением "многие ко многим", и необходимость получать ID определяется именно этим. Причём данные этих сущностей пополняются динамически, то есть в одном модуле может рекламироваться несколько организаций, брендов, товарных категорий и пр., и они постоянно пополняются. И заставлять юзера отдельно заходить в справочники - это резкое торможение процесса. Все эти множественные сущности показываются в своих Grid окна свойств модуля; при сохранении модуля соответствующим образом модифицируются записи в индексных таблицах, реализующих отношение "многие ко многим". Не представляю, как здесь можно использовать ХП. От курсорадаптера отказываться не хочется - уж очень штука удобная; использовать requery неудобно, потому что некоторые справочники содержат десятки тысяч записей, да и проблема найти её потом, нужную запись, после обновления. Не вводить же ещё одно поле, содержаще уникальные значения! Ключи на базе GUID, генерируемых в фоксе, тоже не хочется использовать, сразу размер таблиц растёт. Больше всего напрягает использование @@IDENTITY, потому что ввод многопользовательский, а эта переменная возвращает ID последней добавленной записи. Хотя триггеров на Insert в БД нет, только каскадное удаление и изменение. Что же делать-то? |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
PaulWist Сообщений: 14618 Дата регистрации: 01.04.2004 |
Слушай Вячеслав, а почему бы в момент редактирования документа, при вводе нового значения справочника форма ввода справочника не возвращала бы только, что введённое значение, вполне приемлемый вариант.
------------------ Есть многое на свете, друг Горацио... Что и не снилось нашим мудрецам. (В.Шекспир Гамлет) |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
boba Сообщений: 6269 Откуда: Медвежьи озера- Дата регистрации: 26.03.2001 |
я возился сэтим делом пару месяцев и более
половина событий срабатывает один раз всего если только нет в коде пары tableupdate- cursorfill ( те перезапрос) Как я помню такая же штука раньше была в ремоут вью Второй tableupdate давал правду, но на деле извменений н6е вносил А работало так tableupdate -requery() Как я понял, класс курсор адаптера собран из механизма view и работает по этому сценарию а иначе не работает не только упомянутое вами событие но и куча других Я тоже вел переписку с Микрософт по этому поводу , конкретно с Джимом Сандерсом , они подтвердили все это Може исправят во втором сервис пэке так как уже много людей обратило на это внимание |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
MichaelD Сообщений: 7578 Дата регистрации: 14.05.2005 |
Вячеслав,
- в любом случае, [добавление + получение кода добавленной] должен делать сервер, возвращая клиенту код добавленной - если, как показал Павел, то нужно предусмотреть возврат клиенту списка кодов добавленных записей (строка, массив) для последующего использования на клиенте, если потребуется ------------------ С уважением, Михаил Дроздов, Пермь, Россия |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Влад Колосов Сообщений: 22664 Откуда: Ростов-на-Дону Дата регистрации: 05.05.2005 |
Именно так, в таких сложных случаев View не используется, но используются хранимые процедуры плюс возврат данных (ID).
------------------ Совершенство - это не тогда, когда нельзя ничего прибавить, а тогда, когда нечего убавить. |
Re: CursorAdapter, событие AfterInsert и поле сервера типа IDENTITY | |
---|---|
Вячеслав Клепинин Автор Сообщений: 1597 Откуда: Санкт-Петербург Дата регистрации: 26.03.2004 |
Господа!
Курсор адаптер будет жить! Всё оказалось достаточно просто. Нужно при помощи SQLEXEC добавлять запись непосредственно в таблицу на сервере, одновременно получая значение SCOPE_IDENTITY(), потом обновлять курсор и позиционироваться на запись с полученным ID:
И не нужно насиловать себя всякими AfterInsert и прочими прибамбасами! Огромное спасибо всем откликнувшимся! Исправлено 2 раз(а). Последнее : Вячеслав Клепинин, 07.04.06 13:33 |
© 2000-2024 Fox Club  |