我有一个包含主键字段ID的表。我不想使用Identity,因为我需要为用户提供手动选择新对象的ID的可能性。所以我的想法是:
问题是如何查询和SQL Server表获取第一个免费ID号?
示例1:
ID
--
1
2
10
第一个免费ID是3
示例2:
ID
--
1
2
3
4
首个免费ID为5
有办法吗? 我能想到的是获取最小值和最大值,为可能的值创建一个循环,然后与表数据进行比较,但它涉及到数据库的太多查询。 谢谢!
答案 0 :(得分:7)
您可以找到第一个免费ID作为第一个ID,其中没有" next"值:
select coalesce(min(t.id) + 1, 0)
from table t left outer join
table t2
on t.id = t2.id - 1
where t2.id is null;
编辑:
如果你想处理" 1"作为潜在的缺失值:
select (case when min(minid) > 1 then 1 else coalesce(min(t.id) + 1, 0) end)
from table t left outer join
table t2
on t.id = t2.id - 1 cross join
(select min(id) as minid from table t) const
where t2.id is null;
答案 1 :(得分:1)
测试表
CREATE TABLE ID_TABLE(ID INT)
INSERT INTO ID_TABLE VALUES
(1),(2),(10)
存储过程
ALTER PROCEDURE dbo.usp_GetNextValue
@nxt_ID_Wanted INT = 0,
@nxt_ID_Available INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
-- If user hasnt passed any value get next avilable value
IF (@nxt_ID_Wanted = 0)
BEGIN
SELECT TOP 1 @nxt_ID_Available = ID + 1
FROM
(
SELECT ID , ROW_NUMBER() OVER (ORDER BY ID ASC) AS rn
FROM ID_TABLE
)Q
WHERE ID = rn
ORDER BY ID DESC
IF (@nxt_ID_Available IS NULL)
BEGIN
SET @nxt_ID_Available = 1;
END
END
-- If user has passed a value check if it exists and raise error
ELSE IF EXISTS(SELECT 1 FROM ID_TABLE WHERE ID = @nxt_ID_Wanted)
BEGIN
RAISERROR('Selected ID value already exists',16,1)
SET @nxt_ID_Wanted = 0;
RETURN;
END
ELSE -- else just let the user have the value he/she wanted
BEGIN
SET @nxt_ID_Available = @nxt_ID_Wanted;
END
END
执行程序
DECLARE @ID INT;
EXECUTE dbo.usp_GetNextValue @nxt_ID_Wanted = 6
,@nxt_ID_Available = @ID OUTPUT
SELECT @ID