2010-12-09 23 views
-2

Ich habe eine Tabelle wie soSQL Server 2008

ID   NAME 
----------- ----------- 
1   JON 
2   JIM 
3   BOB 

(3 row(s) affected) 

Was ich seinen Code benötigen eine Nummer zu wählen, die Ausfahrt nicht in der Spalte ID und steckte es in eine Datei so in diesem Fall wird es sein, "4".

Was ich tun muss, ist bei 1 beginnen dann überprüfen 2,3, und so weiter, bis wenn eine Zahl gefunden wird, die nicht in der Tabelle vorhanden ist.

Dieser Code wird in SQL Server 2008

+1

Sie wollen (höchste + 1) oder erste Lücke? – gbn

+3

Und Sie wollen nicht verwenden und Identity-Spalte, weil ... –

Antwort

5

sein, was Sie brauchen, ist ein Zahlen-Tabelle oder Liste:

Declare @MaxValue int; 
Set @MaxValue = 100; 

With Numbers As 
    (
    Select 1 As Value 
    Union All 
    Select Value + 1 
    From Numbers 
    Where Value <= @MaxValue 
    ) 
Select Min(N.Value) 
From Numbers As N 
    Left Join MyTable As T 
     On T.Id = N.Value 
Where T.Id Is Null 
OPTION (MAXRECURSION 0) 
+1

+1, aber Sie müssen möglicherweise eine 'OPTION (MAXRECURSION 0)' zu dieser Abfrage hinzufügen. Um eine CTE-Endlosschleife zu verhindern, können Sie die Anzahl der zulässigen Rekursionsebenen für eine bestimmte Anweisung begrenzen, indem Sie den 'MAXRECURSION'-Hinweis und einen Wert zwischen 0 und 32.767 in der OPTION-Klausel der INSERT-, UPDATE-, DELETE- oder SELECT-Anweisung verwenden. Auf diese Weise können Sie die Ausführung der Anweisung steuern, bis Sie das Codeproblem gelöst haben, das die Schleife erstellt. Der serverweite Standardwert ist 100. Wenn 0 angegeben wird, wird kein Limit angewendet. Es kann nur ein MAXRECURSION-Wert pro Anweisung angegeben werden. –

+0

@KM - übersehen, dass. Habe die Antwort hinzugefügt. – Thomas

1

Können Sie angeben, warum diese benötigen? Es klingt, als könnte es einen besseren Weg geben, um das allgemeine Bedürfnis zu befriedigen.

Wenn jedoch alles, was Sie die nächste Nummer in der Sequenz müssen, dann sollte diese Arbeit:

SELECT MAX(ID) + 1 FROM Table 

Edit: ich von Thomas' Antwort nur bemerkt (und wieder Inspektion der Frage), dass Es sieht so aus, als ob du nach der ersten Lücke suchst, die die nächste Nummer sein kann oder auch nicht. Aber ich denke, der Gesamtpunkt bleibt immer noch ... warum?

Edit: Ich bin froh, dass Sie eine Antwort akzeptiert, aber ich denke immer noch, dass es mehr dazu gibt. Wenn Sie beispielsweise nur eine ID "reservieren" möchten, gibt es mehrere Möglichkeiten, dies zu erreichen.

GUIDs sind gut für anwendungsgenerierte IDs, sollten jedoch aus Leistungsgründen nicht als Primärschlüssel verwendet werden. Sie können eine zweite Spalte als GUID verwenden und diese in Ihrer Anwendung verwenden, sodass eine einfache Spalte mit automatischer Erhöhung der Primärschlüssel ist. Es gibt noch weitere Leistungsüberlegungen, die Sie untersuchen sollten.

Umgekehrt gibt es etwas namens Hi/Lo Algorithm zum Reservieren von Bereichen von Datenbank-IDs. Es verwendet Integer, die sich hervorragend zur Indexierung eignen und großartige Primärschlüssel darstellen. Es hinterlässt Lücken in der Sequenz, aber das ist auch bei einer regulären automatisch generierten Spalte zu erwarten (z. B. wenn ein Datensatz gelöscht wird).

Wenn es eine Anforderung gibt, dass es keine Lücken in den Identifikatoren geben sollte, klingt das wie eine seltsame Geschäftsanforderung und sollte für seine wahren Bedürfnisse analysiert werden. So etwas sollte in Ihrer Datenpersistenz nicht in den Primärschlüssel übergreifen.

+2

Hinweis, wenn Sie dies für INSERT verwenden, erstellen Sie eine Race-Bedingung –

+0

@Conrad Frix: Absolut. Ich meine, es erfüllt das Grundbedürfnis von "Geben Sie mir die nächste Nummer", aber es löst nicht wirklich, was wahrscheinlicher ist, ein tieferes Problem/Anforderung.Dafür sind mehr Informationen erforderlich, da ich sicher bin, dass eine bessere Methode angewendet werden kann, bei der das Feld für den primären Bezeichner nicht manipuliert wird. – David

+0

+1 nettes Update. –