Laden...

Sql Insert mit uniqueidentifier als Rückgabewert

Erstellt von sevenofnine vor 11 Jahren Letzter Beitrag vor 11 Jahren 5.451 Views
S
sevenofnine Themenstarter:in
45 Beiträge seit 2008
vor 11 Jahren
Sql Insert mit uniqueidentifier als Rückgabewert

verwendetes Datenbanksystem: SQLServer 2008

Hallo Zusammen,
ich habe diverse Tabellen die alle das Feld
ID uniqueidentifier --> default (newid())
beinhalten.

Um beim Neueintrag die GUID zu erhalten, sieht mein Commandostring z.B. so aus


declare @temptable table (id uniqueidentifier); 
declare @identity uniqueidentifier; 
Insert into VERSIONS (Datum,Version) OUTPUT inserted.ID into @temptable values ('20130208',2)
Select id from @temptable;

funktioniert prima.
Da ich aber mehrere 100000 Inserts habe und die Performance nicht so toll ist, suche ich nach Optimierungsmöglichkeiten.

Daher meine Frage, gibts ne andere Möglichkeit die Guid des eben geschriebenen Datensatzes zu ermitteln?

Danke für Eure Hilfe
Gerhard

1.346 Beiträge seit 2008
vor 11 Jahren

Du könntest die gui vor dem Insert generieren, und dann dem insert mit übergeben. Dann hättest du sie. Eine andere Möglichkeit kenne ich nicht

LG pdelvo

S
sevenofnine Themenstarter:in
45 Beiträge seit 2008
vor 11 Jahren

geht leider nicht.

Denn die Datensätze könnten auch über einen externen Import in der Datenbank landen, bzw. es werden u.U. Datensätze aus mehreren Datenbanken gemergt,
daher auch die GUID um die Abhängigkeiten zu erhalten

16.830 Beiträge seit 2008
vor 11 Jahren

Die Wahrscheinlichkeit bei GUID eine doppelte ID zu erhalten ist nicht wirklich groß, aber sie ist gegeben.
Daher musst Du bei solch einem Mass-Insert natürlich auch prüfen, ob diese ID nicht doch schon vergeben ist. Auf der SQL-Seite als Default-Wert passiert das automatisch. Hier musst Du es selbst übernehmen.

Ich stimme ab pdevlo zu, dass man bei solchen Situationen durchaus die ID direkt in der Anwendung generiert, wenn sie sowieso direkt benötigt wird.

Edit: wenn das nicht geht, dann bleibt Dir nichts anderes als übrig als bei einem einzelnen Insert die ID eben auch direkt zu lesen.
INSERT INTO VERSIONS (Datu, Version) VALUES(Datum, Version) SELECT SCOPE_IDENTITY()

var lastID = ( GUID )myCommand.ExecuteScalar( );
S
sevenofnine Themenstarter:in
45 Beiträge seit 2008
vor 11 Jahren

Meiner Meinung nach funktioniert SCOPE_IDENTITY() nicht bei GUID,
daher machte ich mir auch die Mühe mit der @temptable... .
Das lesen aus SCOPE_IDENTITY oder ähnlichem ist sicher notwendig.
Aber ich sehe Optimierungspotential eventuell bei


       declare @temptable table (id uniqueidentifier); 

wie kann ich dies optimieren oder ist dies nicht notwendig da schnell genug?

Die Wahrscheinlichkeit bei GUID eine doppelte ID zu erhalten ist nicht wirklich groß, aber sie ist gegeben.

Ist mir bewußt, bei den Metainformationen der 100000++ Dateien gibts genügend andere Fehler, so dass dieser seltene Fall ignoriert werden kann, zumal das Mergen eh optional verwendet wird.

16.830 Beiträge seit 2008
vor 11 Jahren

Ja, hast recht. MSSQL kann das nicht.

502 Beiträge seit 2004
vor 11 Jahren

Ich würde auch zu der Variante mit "Applikation erzeugt GUID und gibt sie an DB weiter" tendieren. Wobei ich bei sowas oft auch einen Mittelweg wähle: Eine SP erzeugt eine GUID, führt dann das INSERT Statement aus und gibt (u.a.) die GUID zurück.

Worüber man sich normalerweise keinerlei Gedanken machen muss, ist die Kollision - und das gilt auch bei einer sehr großen Menge an Daten! Wenn die Systemeigenen Routinen verwendet werden um die GUID zu erzeugen, dann ist das iirc immer ein GUID v4 - und wer sich dabei Gedanken über die Kollisionswahrscheinlichkeit Gedanken macht, der sollte mal darüber nachdenken, ob nicht innerhalb der nächsten 30 Sekunden ein Asteroid auf die Erde stürzt der die komplette Menschheit auslöscht... 😁
Nur so als Tip: Bei Stackexchange.com wird's ganz gut erklärt und Wolfram Alpha liefert die Visualisierung... Bei 10^17 GUIDs liegt die Wahrscheinlichkeit immer noch bei ~ 0,xxx Promille. Das sollte für die meisten praktischen Anwendungfälle genügen 8)

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

F
115 Beiträge seit 2012
vor 11 Jahren

Hi,

ohne SQL-Server gut zu kennen würde ich bei 100tsd Datensätzen auch mal über einen BULK INSERT

http://msdn.microsoft.com/de-de/library/ms188365.aspx
http://msdn.microsoft.com/de-de/library/ms175915.aspx

nachdenken und ggf. alle Tausende Datensätze mal ein Commit setzten, damit das Undo-Log nicht überhitzt.

Und die ID Vorher zu vergeben ist - wenn möglich - sicherlich auch nicht dumm.

Gruß
f_igy

1.378 Beiträge seit 2006
vor 11 Jahren

Es gibt eine coole Möglichkeit unter TSQL alle eingefügten IDs automatisch am Ende des Inserts auszugeben worauf ich erst vor kurzem gestoßen bin:


create table test(Id uniqueidentifier primary key default(newid()), Name varchar(max))
go

insert test(Name)
output inserted.Id
select Name
from
(
	select 'Max' as Name
	union all
	select 'Moritz' as Name
	union all
	select 'Gretchen' as Name
	union all
	select 'Heidi' as Name
)tmp


10418F4B-58CA-44A8-A93E-7B2386E9CE8C
66D0AD18-34D9-49F2-9400-D8ED5C511216
15EA9071-107D-48FD-819C-E7299FE5158A
43CA4000-51D6-4E29-8AF5-25768C343BC6

Lg, XXX