По суті, ваше питання:
Чому я більше не можу займатися такою ризикованою справою, яку мені ніколи не слід було дозволити робити?
Відповідь на це питання значною мірою не має значення (хоча ви можете побачити деякі коментарі Microsoft у цих елементах Connect із запитом про цю функціональність: # 294193 та # 252226). Для повноти мій конспект такий: Можливість вилучити властивість ідентичності була навмисним побічним ефектом наявності в першу чергу здатності возитись із системними таблицями. Це не було призначене для використання багатьма способами, які це було, часто з дуже поганими наслідками, і таким чином його було усунено. Це був бездокументований, непідтримуваний, злом системної таблиці. Можливість змінювати дані в системних таблицях не була видалена, оскільки Microsoft більше не хотіла, щоб ви зламали вихід із стовпця, що був стовпцем ідентичності, його було видалено, оскільки спілкування із системними таблицями надзвичайно ризиковано. Видалення властивості IDENTITY саме по собі не було спеціально націленим видаленням функції, і я б ніколи повністю не довіряв цьому підходу, навіть у стародавні часи, коли це було можливо.
Це сказало, а як ми натомість відповімо на це запитання?
Як видалити властивість Ідентичність стовпця з мінімальним простоєм або без нього?
Це ви можете легко зробити, використовуючи ALTER TABLE ... SWITCH
техніку, я впевнений, що я вперше навчився у нашого Пола Уайта в обхідних шляхах для підключення №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 заповнить цей стовпець, і перевірити будь-які вставки або виписки, які можуть залежати від порядку стовпців або стовпців, які вони повинні вказати. Як правило, я б привітався з усією базою коду за будь-яку згадку про цю таблицю.
Також перегляньте цей сценарій від Іціка Бен-Гана (джерело: ця стародавня стаття ) для іншого способу вирішення цього питання, але тут є рух руху даних, тому він не доставляє вимоги "немає або мінімального простою".