Frage

Ich habe ein SQL-Skript, das Daten einfügt (über INSERT-Anweisungen, die derzeit in die Tausende gehen). Eine der Spalten enthält einen eindeutigen Bezeichner (allerdings keinen IDENTITY-Typ, sondern nur ein einfaches altes int), der in einigen verschiedenen Tabellen tatsächlich eindeutig ist.

Ich möchte meinem Skript eine Skalarfunktion hinzufügen, die die nächste verfügbare ID abruft (d. h.zuletzt verwendete ID + 1), aber ich bin mir nicht sicher, ob dies möglich ist, da es anscheinend keine Möglichkeit gibt, eine globale oder statische Variable innerhalb einer UDF zu verwenden, ich kann keine temporäre Tabelle verwenden und ich kann Es ist nicht möglich, eine permanente Tabelle innerhalb einer Funktion zu aktualisieren.

Momentan sieht mein Skript so aus:

   declare @v_baseID int 
   exec dbo.getNextID @v_baseID out  --sproc to get the next available id
   --Lots of these - where n is a hardcoded value
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', @v_baseID + n ) 
   exec dbo.UpdateNextID @v_baseID + lastUsedn  --sproc to update the last used id

Aber ich möchte, dass es so aussieht:

   --Lots of these
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', getNextID() ) 

Das Hardcodieren des Offsets ist nervig und fehleranfällig.Es ist sehr verlockend, es in eine einfache Skalarfunktion zu packen, aber ich glaube langsam, dass das auf diese Weise nicht möglich ist, da es anscheinend keine Möglichkeit gibt, den Offset-Zähler zwischen Aufrufen beizubehalten.Ist das richtig oder fehlt mir etwas?

Wir verwenden derzeit SQL Server 2005.

Änderungen zur Klarstellung:

Es wird nicht passieren, dass zwei Benutzer darauf klicken.Dies ist ein Upgrade-Skript, das nur einmal und niemals gleichzeitig ausgeführt wird.

Der eigentliche Sproc hat nicht das Präfix sp_, der Beispielcode wurde korrigiert.

Im normalen Gebrauch verwenden wir eine ID-Tabelle und einen Sproc, um bei Bedarf IDs abzurufen. Ich habe nur nach einer saubereren Möglichkeit gesucht, dies in diesem Skript zu tun, das im Wesentlichen nur eine Menge Daten in die Datenbank ablegt.

War es hilfreich?

Lösung

Ich fange an zu glauben, dass dies nicht möglich ist, da es anscheinend keine Möglichkeit gibt, den Offset-Zähler zwischen Aufrufen beizubehalten.Ist das richtig oder fehlt mir etwas?

Ihnen entgeht nichts;SQL Server unterstützt keine globalen Variablen und unterstützt keine Datenänderung innerhalb von UDFs.Und selbst wenn Sie etwas so Umständliches wie die Verwendung von CONTEXT_INFO tun wollten (siehe http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx), können Sie das ohnehin nicht in einer UDF festlegen.

Gibt es eine Möglichkeit, die „Hardcodierung“ des Offsets zu umgehen, indem Sie diese zu einer Variablen machen und die Iteration durchlaufen und die Einfügungen innerhalb dieser Schleife durchführen?

Andere Tipps

Wenn zwei Benutzer gleichzeitig darauf zugreifen, erhalten sie dieselbe ID.Warum haben Sie nicht stattdessen eine ID-Tabelle mit einer Identität verwendet, in diese eingefügt und diese als eindeutige (garantierte) ID verwendet? Dies wird auch viel schneller funktionieren

sp_getNextID

Stellen Sie procs niemals sp_ ​​voran, dies hat Auswirkungen auf die Leistung, da der Optimierer zuerst die Master-Datenbank überprüft, um zu sehen, ob dieser proc dort vorhanden ist, und dann die lokale Datenbank. Auch wenn MS beschließt, eine sp_getNextID in einem Service Pack zu erstellen, wird Ihr Dienst niemals ausgeführt

Es wäre wahrscheinlich mehr Arbeit als es wert wäre, aber Sie können statische C#/VB-Variablen in einer SQL CLR-UDF verwenden. Ich denke also, dass Sie das tun könnten, was Sie wollen, indem Sie diese Variable einfach jedes Mal erhöhen, wenn die UDF vorhanden ist angerufen.Die statische Variable würde natürlich immer dann verloren gehen, wenn die Anwendungsdomäne entladen würde.Wenn Sie also von einem Tag auf den anderen Kontinuität Ihrer ID benötigen, benötigen Sie eine Möglichkeit, beim ersten Zugriff auf NextId alle Tabellen abzufragen, die diese ID verwenden, um den höchsten Wert zu finden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top