Insert und Identity

08/10/2008 - 10:14 von Johannes Busch | Report spam
Hallo zusammen,

also so ganz schlau werde ich aus einigen Darstellungen immer noch
nicht. Das Thema ist eigentlich einfach: Wie ermittle ich einen neu
erzeugten PK nach einem erfolgreichen Insert-Statement. Kursorische
Darstellung:

- Eine Connection MyCnn ist gegeben und überprüft
- Der Insert erfolgt via
dim sc1 as new sqlcommand("Insert INTO...", MyCnn)
sc1.executenonquery

Das funktioniert auch reibungslos.

- Nun frage ich den neuen PK ab via

dim sc2 as new sqlcommand("select (@@identity", MyCnn)
dim o as object= sc2.executescalar

Auch klappt prima.

Aber (und das meine Frage): Was frage ich da eigentlich genau ab?
Bekomme ich definitiv den letzten von MyCnn veranlaßten PK zurück oder
aber (das ist die Befürchtung) den letzten in der DB überhaupt von
irgendwem erzeugten PK?

Unter http://msdn.microsoft.com/de-de/lib...87342.aspx liest sich
das so:
"Nachdem eine INSERT- oder SELECT INTO-Anweisung oder eine
Massenkopieranweisung abgeschlossen ist, enthàlt @@IDENTITY den letzten
von der Anweisung generierten Identitàtswert."

"Von der Anweisung" bezöge sich also auf mein sc1, abfragen tut aber
sc2. Ist das also überhaupt stabil??


Weiterhin: Lassen sich die beiden Statements auch zusammen (so wie in
T-SQL-Batches geht)? Etwa in dieser Art

dim sc as new sqlcommand("(Insert INTO...) (select(@@identity)", MyCnn)
dim o as object= sc2.executescalar

A) Geht das? Und B) Ist das dokumentiert und auch làngerfristig erlaubt?

Ich hoffe, nicht nur verwirrt zu haben ;-)

Johannes Busch
 

Lesen sie die antworten

#1 Stefan Falz [MVP]
09/10/2008 - 02:26 | Warnen spam
Hallo Johannes,

"Johannes Busch" schrieb:

- Nun frage ich den neuen PK ab via

dim sc2 as new sqlcommand("select (@@identity", MyCnn)
dim o as object= sc2.executescalar

Auch klappt prima.



glaub ich nicht :))

dim sc2 as new sqlcommand("select @@identity", MyCnn)

dürfte eher klappen. Die Klammer ( vor @@ wurde entfernt.

Aber (und das meine Frage): Was frage ich da eigentlich genau ab? Bekomme ich definitiv den letzten von MyCnn veranlaßten PK
zurück oder aber (das ist die Befürchtung) den letzten in der DB überhaupt von irgendwem erzeugten PK?



Ersteres. Aber in deinem Fall wàre SELECT SCOPE_IDENTITY() besser geeignet.
Siehe bspw.: http://msdn.microsoft.com/de-de/lib...90315.aspx

Wenn bspw. nach deinem INSERT ein Trigger noch einen Autowert erzeugt, wird
dieser AFAIK von @@IDENTITY zurückgegeben. SCOPE_IDENTITY() liefert den von
Dir erwarteten Wert.

"Von der Anweisung" bezöge sich also auf mein sc1, abfragen tut aber sc2. Ist das also überhaupt stabil??



Wenn Du sicher gehen willst, verwende ein einziges Command Objekt. Das
sollte dann auf jeden Fall passen.



Dim Command As New SqlCommand()
Command.Connection = <Connection>

' Insert Statement absetzen
Command.CommandText = <InsertStatement>
Command.ExecuteNonQuery()

' IDENTITY Wert auslesen
Command.CommandText = "SELECT SCOPE_IDENTITY()"
<Variable> = Command.ExecuteScalar()



Man kann das zwar AFAIK auch in ein einziges Statement packen, das
funktioniert aber nicht mit jeder Datenbank (ok, SCOPE_IDENTITY()
und @@IDENTITY auch nicht aber das kann man ja anpassen :)))

Tschau, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

Ähnliche fragen