我已阅读了几篇关于TSQL Identity Bug的帖子,并且一直在使用SEQUENCE
。但是,我很想知道重置表中SEQUENCE
值的ID
。举个例子:
CREATE SEQUENCE Inc
AS INT
START WITH 1
INCREMENT BY 1
CYCLE
CACHE
-- Quick ability to redo everything if needed:
-- DROP SEQUENCE Inc
-- Our table grabs the next sequence for our ID field:
CREATE TABLE SequenceID(
NewIDField INT DEFAULT NEXT VALUE FOR Inc,
Name VARCHAR(100)
)
INSERT INTO SequenceID (Name)
VALUES ('John')
, ('Tiffany')
, ('Bob')
, ('Jessica')
SELECT *
FROM SequenceID
-- We remove Bob:
DELETE FROM SequenceID
WHERE NewIDField = 3
-- ID value 3 is gone; it moves from 1 to 2 to 4
SELECT *
FROM SequenceID
INSERT INTO SequenceID (Name)
VALUES ('David')
, ('Rosa')
, ('Samuel')
-- ID 3 doesn't exist because the SEQUENCE grabs the next value from 4
SELECT *
FROM SequenceID
-- Let's just reset our ID
;WITH ResetIt AS(
SELECT ROW_NUMBER() OVER (ORDER BY NewIDField) AS ID
, NewIDField AS ExistingID
, Name
FROM SequenceID
)
UPDATE SequenceID
SET NewIDField = ResetIt.ID
FROM ResetIt
WHERE SequenceID.NewIDField = ResetIt.ExistingID
-- Yay!
SELECT *
FROM SequenceID
INSERT INTO SequenceID (Name)
VALUES ('Sarah')
-- Oh Sarah, tsk tsk.
SELECT *
FROM SequenceID
DROP TABLE SequenceID
有没有办法使用SEQUENCE自动执行此操作,我们可以确定最后一个值并从那里开始(类似于RESEED),就像使用IDENTITY
一样,如果我们删除一个值,我们仍然必须{{ 1}},见:
RESEED
答案 0 :(得分:8)
执行更新后,您必须运行一些动态SQL,因为ALTER SEQUENCE只接受RESTART WITH子句的常量:
DECLARE @resetSQL nvarchar(255) = 'ALTER SEQUENCE Inc RESTART WITH ' + (SELECT CAST(MAX(NewIDField)+1 as nvarchar(10)) FROM SequenceID);
exec sp_executesql @resetSQL;