2010-12-09 8 views
-2

J'ai une table comme siSQL Server 2008

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

(3 row(s) affected) 

Ce que je besoin de son code pour sélectionner un numéro qui ne sort pas dans l'ID de la colonne et à le mettre dans un fichier si dans ce cas il sera "4".

Ce que j'ai besoin de faire est de commencer à 1 puis vérifier 2,3, et ainsi de suite jusqu'à ce qu'il trouve un nombre qui n'existe pas dans la table.

Ce code devra être dans SQL Server 2008

+1

Vous voulez (plus haut + 1) ou premier écart? – gbn

+3

Et vous ne voulez pas utiliser et la colonne Identité parce que ... –

Répondre

5

Qu'est-ce que vous avez besoin est une table de numéros ou de la 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, mais vous devrez peut-être ajouter un 'OPTION (MAXRECURSION 0)' à cette requête. Pour empêcher une boucle infinie CTE, vous pouvez limiter le nombre de niveaux de récursivité autorisés pour une instruction particulière en utilisant l'indicateur 'MAXRECURSION' et une valeur comprise entre 0 et 32 ​​767 dans la clause OPTION de l'instruction INSERT, UPDATE, DELETE ou SELECT. Cela vous permet de contrôler l'exécution de l'instruction jusqu'à ce que vous résolviez le problème de code qui crée la boucle. La valeur par défaut à l'échelle du serveur est 100. Lorsque 0 est spécifié, aucune limite n'est appliquée. Une seule valeur MAXRECURSION peut être spécifiée par instruction. –

+0

@KM - Surpassé cela. Ont ajouté à la réponse. – Thomas

1

Pouvez-vous préciser pourquoi vous en avez besoin? Il semble qu'il pourrait y avoir une meilleure façon de satisfaire le besoin global.

Cependant, si vous avez besoin est le numéro suivant dans la séquence, alors cela devrait fonctionner:

SELECT MAX(ID) + 1 FROM Table 

Edit: Je viens de remarquer de la réponse de Thomas (et re-inspection de la question) que Il semble que vous cherchiez le premier écart, qui peut être le numéro suivant ou non. Mais je suppose que le point global reste encore ... pourquoi?

Éditer: Je suis heureux que vous ayez accepté une réponse, mais je pense toujours qu'il y a plus à cela. Par exemple, si vous voulez juste "réserver" un identifiant, il y a plusieurs façons d'y parvenir.

Les GUID conviennent aux ID générés par une application, mais ne doivent pas être utilisés comme clés primaires pour des raisons de performances. Vous pouvez avoir une deuxième colonne en tant que GUID et l'utiliser dans votre application, ce qui permet à une simple colonne d'auto-incrémentation d'être la clé primaire. Il y a d'autres considérations de performance à faire, et vous devriez le rechercher. Inversement, il existe un élément appelé Hi/Lo Algorithm pour réserver des plages d'ID de base de données. Il utilise des entiers, qui sont parfaits pour l'indexation et faire de grandes clés primaires. Il laisse des espaces dans la séquence, mais il faut s'y attendre de toute façon, même avec une colonne générée automatiquement (par exemple, lorsqu'un enregistrement est supprimé).

S'il y a une exigence selon laquelle il ne devrait pas y avoir de lacunes dans les identificateurs, cela ressemble à un besoin commercial étrange et devrait être analysé pour ses véritables besoins. Quelque chose comme ça ne devrait pas déborder dans la clé primaire de votre persistance des données.

+2

Notez que si vous l'utilisez pour INSERT, vous créez une condition de concurrence –

+0

@Conrad Frix: Absolument. Je veux dire, cela répond au besoin fondamental de «donnez-moi le numéro suivant», mais cela ne résout pas vraiment ce qui est plus susceptible d'être un problème ou une exigence plus profonde.Plus d'informations sont nécessaires pour cela, car je suis sûr qu'il y a une meilleure méthode à appliquer qui n'implique pas la manipulation du champ identifiant principal. – David

+0

+1 belle mise à jour. –