12. september 2003 - 10:23Der er
8 kommentarer og 3 løsninger
Primary key ved insert
Hej
Jeg har en tabel med en primary key som automatisk tæller op. Det giver dog et problem i forbindelese med at jeg i min applikation laver en insert, og efterfølgende skal bruge den primary key på den entry der lige er blevet oprettet.
Nogen der kender en holdbar løsning på dette problem?
Jeg vil anbefale dig at oprette posten og så lave en "SELECT MAX(IDfelt) FROM Tabel" bagefter. Umiddelbart er det næste index = det største nuværende index + 1, men det er lidt farligt at regne md, specielt hvis der er flere instanser af din applikation, der kan indsætte poster
Hvis der kører flere instanser af din applikation så du ikke ved hvornår den næste post bliver oprettet, kan du lave hele forløbet i en Stored Procedure
select @@Identity giver det sidst indsatte recordid i en hvilken som helst tabel, så den løsning er ikke holdbar.
Mit bud er at lave en stored procedure til at indsætte og derefter returnere det indsatte recordid med select scope_identity() som sidste statement i proceduren.
<snip> After an INSERT, SELECT INTO, or bulk copy statement completes, @@IDENTITY contains the last identity value generated by the statement. If the statement did not affect any tables with identity columns, @@IDENTITY returns NULL. If multiple rows are inserted, generating multiple identity values, @@IDENTITY returns the last identity value generated. 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. If a trigger is fired after an insert action on a table that has an identity column, and the trigger inserts into another table that does not have an identity column, @@IDENTITY will return the identity value of the first insert. The @@IDENTITY value does not revert to a previous setting if the INSERT or SELECT INTO statement or bulk copy fails, or if the transaction is rolled back.
@@IDENTITY, SCOPE_IDENTITY, and IDENT_CURRENT are similar functions in that they return the last value inserted into the IDENTITY column of a table.
@@IDENTITY and SCOPE_IDENTITY will return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; @@IDENTITY is not limited to a specific scope.
IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope. For more information, see IDENT_CURRENT.
The scope of the @@IDENTITY function is the local server on which it is executed. This function cannot be applied to remote or linked servers. To obtain an identity value on a different server, execute a stored procedure on that remote or linked server and have that stored procedure, which is executing in the context of the remote or linked server, gather the identity value and return it to the calling connection on the local server. </snip>
Som jeg lige har nærlæst ovenstående, så vil select @@identity virke såfremt ens insert ikke danner yderligere Identity-værdier i forbindelse med f.eks. triggers. Der kan så vidt jeg kan se ikke defineres et tabelnavn til @@identity.
Ident_current vil efter min opfattelse ikke virke, da den ikke er begrænset af scope (og derfor lider af samme problem som select max(idfelt))
scope_identity er begrænset af scope - dvs. den procedure, der kalder scope_identity. Den identity-værdi, der skal returneres, skal selvfølgelig samles op af scope_identity umiddelbart efter kaldet af insert i proceduren - evt. i form af en variabel.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.