Avatar billede sparkl Nybegynder
12. september 2003 - 10:23 Der 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?

//Christian
Avatar billede the_bma_man Nybegynder
12. september 2003 - 10:26 #1
select @@identity from table

giver dig sidste id
Avatar billede arne_v Ekspert
12. september 2003 - 10:28 #2
Brug @@identity
Avatar billede renesvane Nybegynder
12. september 2003 - 10:29 #3
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
Avatar billede bennytordrup Nybegynder
12. september 2003 - 10:29 #4
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.
Avatar billede bennytordrup Nybegynder
12. september 2003 - 10:30 #5
select max(idfelt) from tabel er heller ikke en god løsning, hvis der er flere, som indsætter i samme tabel samtidig.
Avatar billede arne_v Ekspert
12. september 2003 - 10:36 #6
rene>

Det virker slet ikke i en fler bruger sammenhæng.

benny>

@@identity er per connection og man ved vel selv hvilken tabel man
har indsat i !
Avatar billede the_bma_man Nybegynder
12. september 2003 - 10:37 #7
benny.tordrup>> så er scop_identity vel heller ikke godt nok.
Så skal der bruges ident_current i stedet for.

sparkl> select ident_current('<dittabelnavnher>')
Avatar billede the_bma_man Nybegynder
12. september 2003 - 10:38 #8
Men sparkl - som arne_v så flot har kommenteret, så virker @@identity altså.
Avatar billede bennytordrup Nybegynder
12. september 2003 - 10:43 #9
Fra Books Online:

<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.
Avatar billede the_bma_man Nybegynder
12. september 2003 - 10:57 #10
Men summa summarum - @@identity virker i den givne situation.
Med 99.99 pct sikkerhed.
Avatar billede sparkl Nybegynder
12. september 2003 - 11:07 #11
Tak for den gode diskution og det hurtige svar.. ;)

Fandt desuden denne på nettet..
http://fox.wikis.com/wc.dll?Wiki~IdentityIssues~SQL
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester