webForumDet fria alternativet

SCOPE_IDENTITY() OCH @@IDENTITY

14 svar · 470 visningar · startad av Nöff

NöffMedlem sedan nov. 2003569 inlägg
#1

Nån som vet vad är det för skillnad på SCOPE_IDENTITY() OCH @@IDENTITY?

PDahlenMedlem sedan apr. 2004778 inlägg
#2

Här är en beskrivning av detta:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tsqlref/ts_sa-ses_6n8p.asp
Började skriva förklaringen här men jag tror att det är bättre att läsa direkt. ;)

Engine^Medlem sedan dec. 20003 887 inlägg
#3

Tro om det kan förklaras såhär:

@@IDENTITY returnerar det senaste ID:t från den sista tabellen som påverkades av den fråga du körde.

SCOPE_IDENTITY returnerar det ID som skapades i den tabell som din fråga först påverkade.

...möjligen.

NöffMedlem sedan nov. 2003569 inlägg
#4

@@IDENTITY returnerar det senaste ID:t från den sista tabellen som påverkades av den fråga du körde.

hmm, kan det månne vara så att @@IDENTITY returnerar sista INSERT:ade ID:et oavsett vilken tabell?.

Sen har vi IDENT_CURRENT som också är en "ID-urplockare" för att lägga lite salt i såret.
Står såhär om den:Returns the last identity value generated for a specified table in any session and any scope.

fan , svårt det här
:l

PDahlenMedlem sedan apr. 2004778 inlägg
#5

Japp, det stämmer att @@IDENTITY returnerar sista INSERT:ade ID:et oavsett tabell. Men det gör Scope_Identity också, så länge det är i samma "scope", t.ex. samma procedur.
I exemplet på msdn så visas det på ett rätt bra sätt. I procen görs en INSERT. Om det inte fanns någon trigger så skulle @@IDENTITY och Scope_Identity returnera samma sak. Men eftersom denna INSERT triggar en annan INSERT så ändras detta. Scope_Identity returnerar ID från den första INSERTen eftersom den skedde i samma "scope", i detta fall samma procedur. @@IDENTITY returnerar ID från den andra INSERTen, den i Triggern, eftersom den skedde sist och vi fortfarande befinner oss i samma session.

IDENT_Current returnerar däremot det sist inlagda ID:t på en angiven tabell. Med andra ord kan du göra INSERTs i tabellerna TZ och TY och ändå få ut senaste ID från en helt annan tabell, t.ex. TX.

Hmm, mycket att tänka på ibland men det är bra att veta om att det finns. Det dyker säkert upp tillfället då detta är väldigt användbart.

Engine^Medlem sedan dec. 20003 887 inlägg
#6

PDahlen skrev:

Hmm, mycket att tänka på ibland men det är bra att veta om att det finns. Det dyker säkert upp tillfället då detta är väldigt användbart.

Hur fungerar SQL Scope med transaktioner? Där skulle det ju vara intressant, eftersom då kan man inte lita på @@IDENTITY. Det känns som om det är där SCOPE_IDENTITY() blir vettigt.

Annars tycker jag nog att det är trevligare att hålla reda på mycket viktiga värden själv.

NöffMedlem sedan nov. 2003569 inlägg
#7

...

Hmm, mycket att tänka på ibland men det är bra att veta om att det finns. Det dyker säkert upp tillfället då detta är väldigt användbart.

Fint. Jag ska använda den i en transaktion, Vilken är den bästa ID-plockaren att använda då tro?, om jag under transaktionen ska hämta ID från flera tabeller?, borde scope räcka om jag lägger SELECT SCOPE() i samma INSERT sats?, och kör iväg med en command.executeScalar() ?, CURRENT kanske inte lämpar sig eftersom den inte tar i samma session?, det är ju viktigt att ID:et tillhör min transaktion session ju.

PDahlenMedlem sedan apr. 2004778 inlägg
#8

Själv så använder jag alltid @@IDENTITY. Detta pga att det hittills alltid har varit det senast inlagda ID jag är ute efter.
Men egentligen så funkar det med alla 3 så länge du lägger dem på rätt ställe i transaktionen. Om du gör flera INSERTs och ska ha ut flera ID så måste du lagra ID-numren i OUTPUT variabler och då kan man ju köra en @@IDENTITY efter varje INSERT.

NöffMedlem sedan nov. 2003569 inlägg
#9

så.

command.commandtext="INSERT INTO tabell (namn) VALUES ('hej') SELECT SCOPE_IDENTITY()";
int ID=Convert.toInt32(command.executescalar())

Torde då bli bra va?, eftersom SCOPE är ju också inom samma scope, @@IDENTITY är ju inte det.

PDahlenMedlem sedan apr. 2004778 inlägg
#10

Ja, det där borde funka fint och om jag förstått allt vi pratat om så skulle

command.commandtext="INSERT INTO tabell (namn) VALUES ('hej') SELECT @@IDENTITY";
int ID=Convert.toInt32(command.executescalar())

returnera samma sak.

Grabbar, har vi lärt oss något? :)
Tjohoo, något att skriva om i bloggen.

LarsGMedlem sedan dec. 200012 464 inlägg
#11

Om det finns en trigger definerad för tabell där man gör insert på en (annan) tabell med identity-attribut så blir det inte samma sak.

command.commandtext="set nocount on INSERT INTO tabell (namn) VALUES ('hej') SELECT @@IDENTITY";
int ID=Convert.toInt32(command.executescalar())
NöffMedlem sedan nov. 2003569 inlägg
#12

en sista fråga bara innan jag lägger in den i min kod.
Är det nödvändigt att separera med ett ; mellan INSERT satsen och SELECT SCOPE/@@IDENTITY ?

Det funkar både och, men vad är bäst?

PDahlenMedlem sedan apr. 2004778 inlägg
#13

Precis, det var vad vi kom fram till tidigare i inläggen. ;)

PDahlenMedlem sedan apr. 2004778 inlägg
#14

En fråga bara.
Nöff, kör du SQL Server? I så fall använd en Stored Procedure. Om du kör nåt annat ignorera detta inlägg. :)

NöffMedlem sedan nov. 2003569 inlägg
#15

jo jag borde använda sp dock. hehe

139 ms totalt · 3 externa anrop · v20260731065814-full.3ab8d573
135 ms — hämta forumlista (db)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)