Я прочитал несколько сообщений о 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
Есть ли способ автоматически выполнять это с ПОСЛЕДОВАТЕЛЬНОСТЬЮ, где мы можем определить последнее значение и начинаем там (по аналогии с переустановкой), так как даже с IDENTITY
, если удалить значение, мы по-прежнему должны RESEED
, см:
CREATE TABLE IDID(
ID INT IDENTITY(1,1),
I INT
)
INSERT INTO IDID (I)
VALUES (1),(2),(3),(4)
SELECT *
FROM IDID
DELETE FROM IDID
WHERE ID = 3
INSERT INTO IDID (I)
VALUES (5),(6),(7)
SELECT *
FROM IDID
DROP TABLE IDID
Похоже, вы пытаетесь достичь так называемого «бесщеточного» столбца идентификатора. Если это так, я бы посоветовал это сделать; это вызывает больше головных болей, чем любой выигрыш, который вы получите. –
Мой совет: Не делай этого! Если эти цифры являются ключами, то повторное использование их - плохая идея. Например, используя ваш код, у Боба есть ключ из 3, но после удаления строки Боба и нумерации таблицы ключ 3 назначается Джессике. Что произойдет, если у Боба появится трудовой договор с «Employee ID 3»? Что, если это система заказов, и Боб появляется со счетом «Номер заказа 3»? Это будет иметь потенциально разрушительные юридические последствия и последствия для соблюдения, не говоря уже о проблемах с целостностью данных. –
Если числа не являются ключами, и вам нужны только их на стадии отчетности, а затем добавляйте их только на стадии отчетности, используя такие функции, как RANK(), DENSE_RANK() и ROW_NUMBER(). –