powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / MS SQL + ADO
21 сообщений из 21, страница 1 из 1
MS SQL + ADO
    #32003599
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может есть у кого примерчик, как по адошному событию WillChangeRecord отменить insert/update и вызвать нужную хранимую процедуру ...?
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003626
AndrewK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А в чем проблема? В обработчике WillChangeRecord параметру adStatus, который передается по ссылке, присваивается значение adStatusCancel, после чего хранимая процедура вызывается любым доступным способом. Примерчики есть в MSDN. То, что происходит именно insert или update можно узнать по значению параметра adReason.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003652
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема в том , как потом вызвать Resync для текущей строчки , если строчка добавляется ...?
Resync нужен т.к. некоторые поля записи триггером формируются)

при нормальном ходе insert'а ADO сама потом вытаскивает идентификатор строчки (select @@identity) и делает Resync (select .... from ... where <имя поля идентити>=<значение из предыдущего селекта> ). Всё это видно если запустить Profiler ...

Если adStatus = adStatusCancel (кстати ошибка какая-то вылетает), то ADO Resync не выполняет ... попытка выполнить его насильно приводит к ошибке... т.к. он не знает значения @@identity ....
В принципе @@identity можно и самому выполнить .... но куда потом его девать(в смысле как его ADO подсунуть)???
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003665
Павел
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Скорее всего придется не обламывать вставку, а решать все на сервере. Не важно что ты вколотишь на клиенте, при соответствующей обработке на сервере .Resync вернет то что надо.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003680
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То-есть не отменять инсерт на клиенте, а отменить его в триггере что-ли ?
Это достаточно неэффективное решение... т.к. допустим в триггере отменяется инсерт и вызывается нужная ХП, а внутри этой хранимой процедуры тоже есть инсерт, что в свою очередь вызовет триггер ... замкнутый круг какой-то ....
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003703
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Скопировано с сайта Новикова Сергея nsa.cat.ru. Автор статьи - Павел Жидков (Кузбас)

"Данные, добавленные в базу данных, не будут отображены в форме, так как они противоречат условиям на базовый источник записей"

Прислал Павел Жидков.
Окончательно обессилив в борьбе с ошибкой в проекте Access'a 2000 "Данные, добавленные в базу данных, не будут отображены в форме, так как они противоречат условиям на базовый источник записей" при вставке записи в таблицу с ключевым полем Identity и триггером On Insert, добавляющим записиии в другую таблицу с ключевым (или не ключевым) полем Identity я решил заглянуть в корень проблемы. Итак:
При работе с SQL сервером через ODBC такой проблемы не возникает, следовательно запускаем ODBC Trace и изучаем вызовы ODBC функций. И вот какая интересная штука - сразу после вставки записи, до COMMIT одна из функций запрашивает @@Identity. (Для тех кто не знает @@Identity это системная переменная (или функция(?)) которая содержит значение последнего поля Identity, сгенерированного при вставке записи). Снова начал эксперементировать с OLE DB Provider for MSSQL, и вскоре выяснил, что этот самый провайдер возвращает Access'у значение @@Identity после Commit, когда @@Identity в результате работы триггера уже приняло значение отличное от значения в поле.
Это со стороны Microsoft безусловно Глюк и баг !!! Но как-то нужно выкручиваться. И вот что мне пришло в голову: Если отказаться от Identity Вообще, то неизбежно возникнет проблема создания уникального значения для ключевого поля. В однопользовательской среде это, собственно, и не проблема -бери MAX от значений поля, наращивай на 1 и всавляй. Но вот в многопользовательской среде это, во первых, замедлит работу и вызовет нежелательную блокировку таблицы, а во вторых может привести к нарушению уникальности ключа из-за попытки одновременно вставить запись разными пользователями. Но есть замечательная штука - uniqueidentifier. Используя его в качестве ключевого поля проблему удалось решить). Но не всем и далеко не всегда удобно и необходимо использовать uniqueidentifier, к тому же сортировка по полю этого типа невозможна (хотя эти проблемы обойти легко). Напрашивался вывод: нужно заставить вернуть @@Identity нужное Access'y значение. Мне удалось найти только один способ (да простят меня знатоки T-SQL за глумление над полезными операторами !)

В начале триггера/процедуры
Declare @Idt As int, @SqlStr As Varchar(100)
Set @Idt = @@Identity
...

В конце триггера/процедуры
Set @SqlStr = 'Select Identity (Int, ' + Cast(@Idt As Varchar(10)) + ', 1) As id Into #Tmp'
Execute (@SqlStr)

С наилучшими пожеланиями
Павел Жидков
Программист вечно работающий не по специальности.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003704
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извините, опечатался. Не nsa.cat.ru, а nsa.chat.ru
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003746
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема не в том, как вернуть нужный @@identity, а в том куда (т.е. в какое свойство/параметр объекта рекордсет) его потом засунуть ...
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003784
Павел
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Полпробуй запихнуть его в динамическое свойство рекордсета "Resync Command". С помощью Resync Command можно вернуть рекордсету что угодно, лиш бы форматы соответствующих полей совпадали. В качестве Resync Command можно использовать текст SQL (Select * From Table1 Where id = ?, или без таблиц(ы) Select 123 as id, 'Bred' As Value, или даже Select ? as id, 'Bred' As Value), процедуру (с параметрои) или даже представление. Лиш бы все это вернуло одну строку. Вместо '?' ADO подставит значение ключа текущей записи. Вот только я не уверен, что при отмене вставки в рекордсет это сработает. Точно сработает если вставка прошла удачно. Как победишь свою проблему - кинь в конфу, это интересно.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32003888
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ok, значение @@identity я подсунул в св-во "Resync Command"....
Теперь проблема вызвать метод
Resync(ADODB::adAffectCurrent,ADODB::adResyncAllValues)
в обработчике событий (WillRecordChange,RecordChangeComplete) это сделать не получается ...
вылетает ошибка "Consumer's event handler called a non-reentrant method in the provider."
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004021
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ok, значение @@identity я подсунул в св-во "Resync Command"....
Теперь проблема вызвать метод
Resync(ADODB::adAffectCurrent,ADODB::adResyncAllValues)
в обработчике событий (WillRecordChange,RecordChangeComplete) это сделать не получается ...
вылетает ошибка "Consumer's event handler called a non-reentrant method in the provider."
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004300
Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi, Alexander.

ИМХО проблема в том, что Update так и так происходит после вставки даже если 'Update_Resync'=adResyncNone, видно по adStatus, что по моему вообще-то странновато.
Поэтому пока статус датасета не станет снова dsBrowse эта ошибка будет, помоему даже если в OnAfterPost поставить Resync.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004467
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А где в MSDN есть подобный пример ?
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004536
Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Забей!!!

Не знаю, но я перелопатил весь ADO SDK и даже весь MS онлайн(KB).(MSDN у меня старый)
Бесполезно, только реквери. Ситуация тупик. Они сами признаются, что идентити не подставить.
Проблема в том, что АДО считает себя умнее всеХ =8[] и делает ресинк только для уже существующих записей. Если делать через кешированные изменения(BatchOptimistic), то команда селект с твоим подставленным идентити реально не выполняется(глянь SQLProfiler), а если не кешированные, то она тут же орет, что запись удалена.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004604
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Requery тоже не помогает. При попвтке вызвать pRS->Requery(-1) внутри WillRecordChange вылетает ошибка "Operation is invalid within the event"....

Последовательность действий такая (внутри WillRecordChange)
1. Вызов хранимой процедуры
2. pRS->Requery(-1); (как вариант вытащить @@IDENTITY, заполнить "Resync Command", вызвать pRS->Resync)
3. *adStatus=adStatusCancel;

Мож я что не так делаю ?
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004816
Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем я добился, чего хотел, могу патентовать
)))

Похоже, что любая рекурсия в этих события, будет вызывать этот еррор.
Мне проще, я делаю все навороты не в обработчиках.
И потом, смотри мой предыдущий мессадж, про реальную НЕРАБОТУ Ресинка.
Очень много я времени потратил, на осознание того, что обязательно нужно, чтобы Unique_Table была и в исходном селекте и в Resync_Command, иначе сам Resync на сервер уходить будет и возвращаться будет, но будет неизвестный еррор(-2147467259) уже на клиенте в самый последний момент. Первый раз я столкнулся с этим когда хранимую процедуру пытался использовать для ресинка, теперь понял в чем проблема была. Тепер и ХП работает.
Так, что в этом месте Павел был не прав. Так что я не прерываю инсерт, а после него делаю ресинк, правда почему-то стандартно ругается(хотя значения идентити правильные), но ручками сформированный ресинк после инсерта работает. С апдейтом проблем нет вообще.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004821
Павел
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Осталось уточнить версию ADO и что в качестве клиента юзается. В Aссеss 2000 все как я писал. Честно-честно.
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004876
Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi, Павел.

Может и насчет ресинка для Аксес2000 правда, но вот то, что Вы называете глюком и багом для СКЛСервера и идентити совсем не глюк.

IDENT_CURRENT returns the last identity value generated for a specific table in any session and any scope.
@@IDENTITY returns the last identity value generated for any table in the current session, across all scopes.
SCOPE_IDENTITY returns the last identity value generated for any table in the current session and the current scope.

Почувствуйте разницу!!!
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004889
Павел
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А я и не утверждал никонда, что это баг сервера! Я говорил о компонентах доступа, где эта ситуация не предусмотрена!

И Вы почувствуйте!!!
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32004922
Alexander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Vladimir : А кусок кода можешь запостить ?
...
Рейтинг: 0 / 0
MS SQL + ADO
    #32005464
Vladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Праздники, знаете ли.

Кусок кода тут не поможет.
ВсЁ ниже сказанное только для 2000. Тут много + и - так, что каждый сам выбирает.
Итак, идентити я так и не подставил, значит прерывать инсерт нельзя. Делаем вид с опцией метадата, чтобы модификация вида шла, а не таблиц, в его триггере делаем, что хотим. При этом получаем проблему с ресинком, так как вид не может быть в UniqueTable. Поэтому в исходный селект добавляем нужную нам таблицу(поля берем только из вида, просто в FROMе она нам нужна, не забудь еЁ и в самом ResyncCommand), которую и укажем в качестве UniqueTable. После инсерта делаем ресинк(см. предыдущее письмо, из-за того что он сам не работает нужно убрать из UpdateResync всЁ кроме adResyncAutoIncrement, потом восстановишь). После редактирования ничего наворачивать в принципе не надо, только проблема в том, что у вида нет индекса и UpdateCriteria=adCriteriaKey не помогает, и запросы АДО будет генерить по измененным полям, т.к. такое where условие явно -, то апдейт запросы я генерю сам(выполнить их легко по всякому, строк не возвращает), моему датасету делаю кансел и ресинк. При всЁм при этом курсор может быть кешированным или нет, как хочешь.

Вот такой "изврат", блин.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / MS SQL + ADO
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]