Ошибка при добавлении данных в форме ADP + SQL Server
Начальные условия этой ситуации: 1. У вас есть таблица с автоинкрементным полем
2. Есть триггер на эту таблицу, имеющий команду INSERT в другую таблицу. Причем очень важно чтобы в этой таблицы было автоинкрементное поле.
3. Форма в проекте Access 2000 (хотя клиент в данном случае может не играть роль)
При соблюдении всех этих условий, вы гарантированно получите сообщение об ошибке:
"Данные, добавленные в базу данных, не будут отображены в форме, так как они противоречат условиям на базовый источник записей." При этом в форме добавленной записи не видно, но при обновлении все восстанавливается на свои места.
Сообщение можно погасить способом, который описывал Сергей Вакшуль по совету Муслима Князева
/access/article.asp?id=366 (при этом даже будет видна добавленная запись). Но если у вас есть умолчания на поля таблицы, то значения этих полей в форме отображаться будут не корректно до следующего обновления.
Суть ошибки:
Все достаточно просто если рассмотреть как работает Access в этом случае.
Когда вы добавляете строку в таблицу вам надо знать значения ключа добавленной записи, чтобы отобразить в форме. Значения ключа можно узнать командой SELECT @@IDENTITY.
Смысл этой команды такой (BOL: Returns the last-inserted identity value. If the statement fires one or more triggers that perform inserts that generate identity values, calling @@IDENTITY immediately after the statement returns the last identity value generated by the triggers)
Так как у вас в триггере происходит операция INSERT, то Access выполняя операцию SELECT @@IDENTITY получает ключ от другой таблицы и соответственно ругается.
Как разрешить эту ситуацию:
SQL 2000 (проверена мною)
Вместо обычного постпроцессорного триггера использовать триггер INSTEAD OFF, который вызывается вместо вашей операции. В теле триггера вы выполняете все действия, а потом из таблицы INSERTED заносите данные в целевую таблицу. Тем самым Access получит корректное значение Identity так как последний INSERT был как раз в целевую таблицу
SQL 7 и выше (не проверял, просто версия) (Если кто-то может проверить прошу прислать результаты автору или мне. Прим. вед. раздела)
* Например, в Ассеss-e на событие After Insert вызывать команду SELECT SCOPE_IDENTITY(), которая вернет значение поля Identity из той таблицы, на которую вы определили триггер. Эта команда возвращает значения только из вашей сессии.
Аналогичная ей команда IDENT_CURRENT('table_name') работает по всем сессиям, что не делает ее привлекательной для этого случая.
С полученным значением можно распоряжаться по разному, в зависимости от условий задачи.
P.S. Напрашивается еще решение. Например, в триггере вставить последнюю команду IDENT_CURRENT('table_name') - проверял, не работает!