2013-04-08 4 views
4

Мое приложение вставляет некоторые данные в таблицу.Stop trigger change scope_identity

insert into this_Table (id, value, value) 

Я создал триггер, который делает простую вставку, в другую таблицу с первичным ключом.

insert into temp_wc_triggertest values ('test', GETDATE()) 

Моя проблема в том, то приложение пытается искать scope_identity, с первой вставки. Однако он перезаписывается триггером, который изменяет идентификатор области действия на первичный ключ temp_wc_triggertest.

Как я могу остановить перезагрузку триггера scope_identity?

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

Это на SQL Server 2008 R2

EDIT: Я посмотрел на код, и он действительно использует scope_identity

+5

Если вы использовали идентификатор @@, то это действительно так, но поскольку вы используете scope_identity, это не должно происходить. –

+0

Мне сообщили, что это scope_identity, но так и не подтвердили. Какой бы он ни был, я уверен, что он меняется. – Wayneio

+0

@ Микаэль Эриксон прибил его. Когда вы говорите «приложение пытается искать« scope_identity », что это значит? Как/где/когда он получает идентификатор области? –

ответ

1

Причина, по которой он переписывает идентификатор области видимости, по-прежнему не ясен, возможно, это связано с упомянутой ошибкой.Однако исправление было найдено:

временная таблица была создана «temp_wc»

Затем в конце спускового крючка, вставка идентичность была включена для этой таблицы, и вставка была сделана, для ID, что мы хотите сохранить после срабатывания триггера. Этот метод можно рассматривать как перезапись переопределенной видимости области.

SET IDENTITY_INSERT ON 
INSERT INTO temp_wc VALUES (@ID, 'fix scope identity error') 
+1

Если это исправлено, ваш код не использовал 'SCOPE_IDENTITY' –

+0

Отличное предложение - я использовал временную таблицу в своем триггере, и это сработало (что меня удивило, потому что я задавался вопросом, объем временной таблицы будет длиться достаточно долго). если (выберите кол (1) от вставлено) = 1 начать \t создать таблицу #TempIdTable (ResetIdentity ИНТ тождество (1, 1)) \t набор IDENTITY_INSERT #TempIdTable на \t вставки в #TempIdTable (ResetIdentity) \t выберите UserID из вставленного \t set identity_insert #TempIdTable off end –

0

Использование SELECT IDENT_CURRENT(‘tablename’)

«возвращает последнее значение IDENTITY производится в таблицу, независимо от соединения, которое создало значение, и независимо от области действия оператора, который произвел значение ».

См. Эту ссылку для получения более подробной информации.

http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

+0

Это должно быть помещено в код приложения после триггера. Однако у меня есть только доступ к триггеру, поэтому мне нужно остановить триггер, фактически изменяя scope_identity. – Wayneio

+4

Если у вас несколько клиентов, добавляющих строки в то же время, используя 'IDENT_CURRENT()', это не такая хорошая идея. Вы можете получить значение идентификатора, созданное другим клиентом. –

2

Ваш клиент, безусловно, используя @@IDENTITY вместо SCOPY_IDENTITY()

Вот это SQL скрипку с некоторым кодом вы можете проверить на.

SQL Fiddle

сервера Настройка MS SQL 2008 схемы:

create table T1(ID int identity(1,1)); 
create table T2(ID int identity(1000, 1)); 

go 

create trigger tr_T1 on T1 for insert 
as 
insert into T2 default values; 

Запрос:

insert into T1 default values 

select @@identity as "@@identity", 
     scope_identity() as "scope_identity()" 

Results:

| @@IDENTITY | SCOPE_IDENTITY() | 
--------------------------------- 
|  1000 |    1 | 
+0

Спасибо. Это было полезно, я не знал, что вы можете выбрать личность в разных точках. Я сделал это, и личность всегда возвращается как ожидаемая (идентификатор из первой таблицы). Я думаю, что это будет связано с ошибкой, отмеченной выше – Wayneio