2010-12-09 114 views
-2

我有一個像這樣SQL Server 2008的

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

(3 row(s) affected) 

我需要它的代碼是什麼,選擇一個數字,不退出在列ID和出把它放到一個文件中,以便在這種情況下這將是一個表「4」。

我需要做的是從1開始,然後檢查2,3,依此類推,直到找到表中不存在的數字。

此代碼必須是SQL Server 2008

+1

你想要(最高+ 1)還是第一個差距? – gbn 2010-12-09 20:28:17

+3

而您不想使用Identity標識列,因爲... – 2010-12-09 20:28:23

回答

5

你需要的是一個數字表或列表:

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,但您可能需要爲此查詢添加一個「OPTION(MAXRECURSION 0)」。爲了防止CTE無限循環,可以通過在INSERT,UPDATE,DELETE或SELECT語句的OPTION子句中使用'MAXRECURSION`提示和0到32,767之間的值來限制特定語句允許的遞歸級別數。這使您可以控制語句的執行,直到解決創建循環的代碼問題。服務器範圍的默認值爲100.指定0時,不應用任何限制。每個語句只能指定一個MAXRECURSION值。 – 2010-12-09 20:35:55

1

可以指定你爲什麼需要這個?這聽起來似乎可能有更好的方式來滿足整體需求。

但是,如果你需要的是序列中的下一個數字,那麼這應該工作:

SELECT MAX(ID) + 1 FROM Table 

編輯:我剛剛從托馬斯的答案發現(並重新檢查的問題),其它看起來像你正在尋找第一個差距,這可能會或可能不是下一個數字。但我想整體觀點仍然存在......爲什麼?

編輯:我很高興你接受了答案,但我仍然認爲還有更多。例如,如果你只是想能夠「保留」一個ID,那麼有幾種方法可以實現這一點。

GUID適用於應用程序生成的ID,但不應將其用作性能原因的主鍵。您可以將第二列作爲GUID並在應用程序中使用該列,從而允許簡單的自動增量列作爲主鍵。有進一步的性能考慮,你應該研究它。

相反,有一些名爲Hi/Lo Algorithm的數據庫ID預留範圍。它使用整數,這對索引和製作優秀的主鍵非常有用。它會在序列中留下空白,但即使使用常規自動生成的列(例如刪除記錄時)也是如此。

如果要求標識符中不應該有空白,這聽起來像是一個奇怪的業務需求,應該分析它的真實需求。類似的東西不應該擴展到數據持久性的主鍵。