Ваш вопрос, по сути:
Почему я больше не могу делать эту рискованную вещь, которую мне никогда не следовало делать?
Ответ на этот вопрос в значительной степени не имеет значения (хотя вы можете увидеть некоторые комментарии Microsoft в этих элементах Connect с просьбой об этой функции: # 294193 и # 252226). Для полноты изложения я делаю следующее: возможность удалить свойство удостоверения была непреднамеренным побочным эффектом, связанным с возможностью сначала связываться с системными таблицами. Это не было предназначено для использования во многих отношениях, часто с очень плохими последствиями, и, таким образом, оно было удалено. Это был недокументированный, неподдерживаемый взлом системной таблицы. Возможность изменять данные в системных таблицах не была удалена, потому что Microsoft больше не хотела, чтобы вы взламывали выход из столбца, являющегося столбцом идентификаторов, она была удалена, потому что хищение с системными таблицами чрезвычайно рискованно. Само по себе удаление свойства IDENTITY не было целенаправленным удалением, и я бы никогда полностью не доверял этому подходу, даже в древние времена, когда это было возможно.
Тем не менее, как насчет того, чтобы ответить на этот вопрос?
Как удалить свойство IDENTITY столбца с минимальным временем простоя или без него?
Вы можете легко это сделать, используя ALTER TABLE ... SWITCH
технику, которую, я уверен, я впервые узнал от нашего собственного Пола Уайта в обходных решениях для Connect # 252226 . Быстрый пример, приведенный в этой простой таблице:
CREATE TABLE dbo.Original
(
ID INT IDENTITY(1,1) PRIMARY KEY,
name SYSNAME
);
GO
INSERT dbo.Original(name) VALUES(N'foo'),(N'bar');
GO
SELECT * FROM dbo.Original;
GO
Результаты:
ID name
-- ----
1 foo
2 bar
Теперь давайте создадим теневую таблицу и переключимся на нее, затем удалим старую таблицу, переименуем новую и затем возобновим обычную деятельность:
CREATE TABLE dbo.New
(
ID INT PRIMARY KEY,
name SYSNAME
);
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
ALTER TABLE dbo.Original SWITCH TO dbo.New;
DROP TABLE dbo.Original;
EXEC sys.sp_rename N'dbo.New', N'Original', 'OBJECT';
COMMIT TRANSACTION;
GO
INSERT dbo.Original(ID,name) VALUES(3,N'splunge');
UPDATE dbo.Original SET ID = 6 WHERE ID = 1;
GO
SELECT * FROM dbo.Original;
GO
Результаты:
ID name
-- -------
2 bar
3 splunge
6 foo
Теперь убери
DROP TABLE dbo.Original;
Это только операция с метаданными, без перемещения данных, и она блокирует других пользователей только во время обновления метаданных. Но, по общему признанию, это очень упрощенный пример. Если у вас есть внешние ключи или вы используете другие функции, такие как репликация, сбор данных изменений, отслеживание изменений и т. Д., Вам может потребоваться отключить или удалить некоторые из них перед внесением этого изменения (я не проверял все комбинации). Что касается внешних ключей, см. Этот совет, который показывает, как создавать сценарии для удаления и повторного создания всех (или выбранных) ограничений внешнего ключа.
Кроме того, вам нужно будет обновить код приложения, чтобы SQL Server не заполнил этот столбец, и проверить все операторы вставки или выбора, которые могут зависеть от порядка столбцов или столбцов, которые они должны указать. Как правило, я бы взял всю вашу кодовую базу для любого упоминания этой таблицы.
Также посмотрите этот сценарий от Ицик Бен-Гана (источник: эта древняя статья ) для другого способа справиться с этим, но здесь задействовано перемещение данных, поэтому он не выполняет требования «нет или минимальное время простоя».