2010-12-09 155 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预留范围。它使用整数,这对索引和制作优秀的主键非常有用。它会在序列中留下空白,但即使使用常规自动生成的列(例如删除记录时)也是如此。

如果要求标识符中不应该有空白,这听起来像是一个奇怪的业务需求,应该分析它的真实需求。类似的东西不应该扩展到数据持久性的主键。