Восстановить потерянную личность - PullRequest
0 голосов
/ 01 октября 2018

Есть ли способ воссоздать значение идентификатора таблицы SQL Server, если операторы не выполнены внутри блока транзакции?

Пожалуйста, пройдите по следующему коду:

DECLARE @IdentityTable AS TABLE (ID INT IDENTITY(1, 1), Description VARCHAR(50))

INSERT INTO @IdentityTable (Description) 
VALUES('Test1')

BEGIN TRY 
BEGIN TRANSACTION IdentityTest
    INSERT INTO @IdentityTable (Description) 
    VALUES('Test2')

    INSERT INTO @IdentityTable (Description) 
    VALUES(1/0)

    COMMIT TRANSACTION IdentityTest
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION IdentityTest
END CATCH

INSERT INTO @IdentityTable (Description) 
VALUES('Test4')

SELECT * FROM @IdentityTable

Result

Тождество № 3 потеряно из-за ROLLBACK TRANSACTION.Можно ли его вернуть?

1 Ответ

0 голосов
/ 01 октября 2018

Вы пытаетесь использовать свойство IDENTITY для генерации последовательных чисел и их сохранения;это не то, для чего IDENTITY.Он предназначен для обеспечения возрастающего значения на основе текущего начального числа (само по себе (без ограничения PRIMARY KEY или UNIQUE INDEX), он даже не гарантирует уникальность, поскольку начальное число можно изменить ( благодаря HoneyBadger за напоминаниея так рано утром )).

Если INSERT не удастся, значение IDENTITY все равно будет увеличиваться.Кроме того, если бы вы должны были DELETE строка из таблицы, это не привело бы к соответствующему обновлению их каждой "последней" строки;таким образом, у вас также будет пробел.

Единственный гарантированный способ получения возрастающего значения - использование функции, подобной ROW_NUMBER при времени выполнения .Например:

SELECT ROW_NUMBER() OVER (ORDER BY ID) AS cID,
       Description
FROM YourTable;

В разделе Примечания документации конкретно указано, что последовательные значения не гарантированы:

Столбцы идентификаторовможет быть использован для генерации ключевых значений.Свойство удостоверения в столбце гарантирует следующее:

...

Последовательные значения в транзакции - Транзакция, вставляющая несколько строк, не гарантирует получение последовательных значений длястроки, потому что другие параллельные вставки могут произойти в таблице.Если значения должны быть последовательными, то транзакция должна использовать монопольную блокировку таблицы или уровень изоляции SERIALIZABLE.

Последовательные значения после перезапуска сервера или других сбоев - SQL Server может кэшировать значения идентификаторовпо соображениям производительности и некоторые из присвоенных значений могут быть потеряны во время сбоя базы данных или перезапуска сервера.Это может привести к пробелам в значении идентичности при вставке.Если пропуски неприемлемы, приложение должно использовать собственный механизм для генерации значений ключей.Использование генератора последовательностей с параметром NOCACHE может ограничить пропуски транзакциями, которые никогда не фиксируются.

Повторное использование значений - Для данного свойства идентификатора с определенным начальным значением / приращением значения идентификаторане используется двигателемЕсли конкретный оператор вставки завершается неудачно или если оператор вставки откатывается, то использованные значения идентификаторов теряются и больше не будут генерироваться.Это может привести к пробелам при генерировании последующих значений идентичности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...