2010-03-05 11 views
15

Po wykonaniu wstawki wybieram SCOPE_IDENTITY lub @@IDENTITY.W jaki sposób SCOPE_IDENTITY może zwrócić wartość null, gdy nie ma IDENTITY @@?

SCOPE_IDENTITY zwraca wartość null, ale @@IDENTITY nie.

Nie rozumiem, jak to jest możliwe.

Czy możesz wymyślić powód, dlaczego tak się dzieje?

+3

Czy możesz podać więcej szczegółów ... np. pokaż kod, na który wywoływana jest funkcja SCOPE_IDENTITY(), i wyjaśnij inne zmienne (np. czy istnieje wyzwalacz?). –

Odpowiedz

1

Znalazłem MSDN:

SCOPE_IDENTITY funkcja() powróci do wartości zerowej, gdy funkcja jest wywoływana przed jakimikolwiek INSERT do kolumny tożsamości występują w tym zakresie.

można przeczytać tutaj: http://msdn.microsoft.com/en-us/library/ms190315.aspx

Twój kod SQL byłoby bardzo pomocne.

15

tutaj jest jednym z przykładów, jak SCOPE_IDENTITY() będzie null ale @@ IDENTITY będzie miała wartość:

wstawić do tabeli bez tożsamości, że tabela ma wyzwalacz insert że wstawia do tabeli historii z tożsamością . SCOPE_IDENTITY() będzie null (brak tożsamości w zakresie lokalnym), , ale @@ TOŻELOŚĆ zgłosi tożsamość z wyzwalacza.

FYI, jest to znany błąd z SCOPE_IDENTITY(): https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

Najprościej z tożsamością jest użycie wyjście do, można go uchwycić zestaw identyfikatorów i nie podlega SCOPE_IDENTITY() bug:

declare @x table (tableID int identity not null primary key, datavalue varchar(10)) 
declare @y table (tableID int, datavalue varchar(10)) 

INSERT INTO @x values ('aaaa') 
INSERT INTO @x values ('bbbb') 
INSERT INTO @x values ('cccc') 
INSERT INTO @x values ('dddd') 
INSERT INTO @x values ('eeee') 


INSERT INTO @x 
    (datavalue) 
    OUTPUT INSERTED.tableID, INSERTED.datavalue  --<<<<OUTPUT INTO SYNTAX 
    INTO @y           --<<<<OUTPUT INTO SYNTAX 
SELECT 
    'value='+CONVERT(varchar(5),dt.NewValue) 
    FROM (SELECT id as NewValue from sysobjects where id<20) dt 
    ORDER BY dt.NewValue 


select * from @x 
select * from @y 
+0

Chociaż nie sądzę, że konieczne było uzyskanie tak szczegółowych informacji na temat niejasnego błędu, który pojawia się tylko wtedy, gdy wstawiasz kilka wierszy i próbujesz odzyskać pojedynczą tożsamość. 'SCOPE_IDENTITY()' działa bez problemu w 99% przypadków.Ponownie, wszystko to jest poprawne, ale dla kogoś, kto nadal uczy się różnicy między '@ ID IDENTYCJĄ" i 'SCOPE_IDENTITY()' może to być trochę przytłaczające. – Aaronaught

+2

@Aaronaught, OP nie dostarcza kodu INSERT, może to być INSERT-SELECT, który używa paralelizmu. Dlaczego nawet założyłem, że istnieje 1% szansa na to! ;-) Przynajmniej w mojej odpowiedzi przedstawiam dwa różne sposoby, że @@ Tożsamość i SCOPE_IDENTITY() mogą mieć różne wartości, a nie tylko ich definicje BOL. –

11

KM uderzył w sedno:

  • @@IDENTITY podaje ostatnią wprowadzoną wartość IDENTYFIKACJI - bez względu na to, w której tabeli został wstawiony (pomyśl wyzwala, np. do tabel kontrolnych! Lub nawet kaskada wyzwalaczy .....)

  • podaje ostatnią IDENTYFIKACJĘ wstawioną w zakresie wyciągu, np. na stole (ów) własne, rzeczywiste stwierdzenie odwołania (nie te, które mogły zostać dotknięte przez wyzwalacz)

+1

SCOPE_IDENTITY() nie zwraca poprawnych wyników, gdy używany jest paralelizm: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811 –

+1

Najbardziej lubię tę odpowiedź - konkretną i na temat. – Aaronaught

+0

jak ta odpowiedź odpowiada na pytanie? Jakie jest rozwiązanie polegające na utrzymywaniu scope_identity w zakresie? to prawdziwy drugi problem w jego problemie. – PositiveGuy

5

SCOPE_IDENTITY będą również zwracać NULL, gdy wkładka jest sp_executesql jak już nie w to zakres INSERT!

Powiązane problemy