SQL Server как удалить личность из столбца
Есть ли простой способ удалить идентификатор из таблицы в SQL Server 2005?
Когда я использую Management Studio, он генерирует script, который создает зеркальную таблицу без идентификатора, копирует данные, удаляет таблицу, затем переименовывает зеркальную таблицу и т.д. Этот script имеет 5231 строку, потому что эта таблица/столбец имеет много отношений FK.
Мне было бы гораздо комфортнее запускать простой вариант/падение. Любые идеи?
ИЗМЕНИТЬ
Я думаю, что я собираюсь пойти с 5,231 строк script из Enterprise Manager. Тем не менее, я собираюсь разбить его на более мелкие части, которые я могу запустить и лучше контролировать. Эта таблица "ведет себя странно", если вы попытаетесь удалить 1 строку (даже одну, которую вы только что вставили, которая не находится в какой-либо другой таблице FK), вы получите эту ошибку:
delete MyTable where MyPrimaryKey=1234
Msg 8621, Level 17, State 2, Line 1
The query processor ran out of stack space during query optimization. Please simplify the query.
Несомненно, все FK. Мы прекратим доступ к нашему приложению и запустим его в однопользовательском режиме, когда мы внесем эту схему и связанные с ней изменения приложения. Тем не менее, нам нужно, чтобы это работало быстро, и мне нужно понять, сколько времени это займет. Я предполагаю, что мне просто нужно будет протестировать, протестировать, протестировать.
Ответы
Ответ 1
Если вы находитесь на SQL Server 2005 или более поздней версии, вы можете сделать это как простое изменение метаданных (NB: не требуется версия, поддерживающая разделение, как я изначально указал).
Пример кода, бесстыдно украденного из обходного пути Пола Уайта на этот элемент Microsoft Connect.
USE tempdb;
GO
-- A table with an identity column
CREATE TABLE dbo.Source
(row_id INTEGER IDENTITY PRIMARY KEY NOT NULL, data SQL_VARIANT NULL);
GO
-- Some sample data
INSERT dbo.Source (data)
VALUES (CONVERT(SQL_VARIANT, 4)),
(CONVERT(SQL_VARIANT, 'X')),
(CONVERT(SQL_VARIANT, {d '2009-11-07'})),
(CONVERT(SQL_VARIANT, N'áéíóú'));
GO
-- Remove the identity property
BEGIN TRY;
-- All or nothing
BEGIN TRANSACTION;
-- A table with the same structure as the one with the identity column,
-- but without the identity property
CREATE TABLE dbo.Destination
(row_id INTEGER PRIMARY KEY NOT NULL, data SQL_VARIANT NULL);
-- Metadata switch
ALTER TABLE dbo.Source SWITCH TO dbo.Destination;
-- Drop the old object, which now contains no data
DROP TABLE dbo.Source;
-- Rename the new object to make it look like the old one
EXECUTE sp_rename N'dbo.Destination', N'Source', 'OBJECT';
-- Success
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
-- Bugger!
IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
PRINT ERROR_MESSAGE();
END CATCH;
GO
-- Test the the identity property has indeed gone
INSERT dbo.Source (row_id, data)
VALUES (5, CONVERT(SQL_VARIANT, N'This works!'))
SELECT row_id,
data
FROM dbo.Source;
GO
-- Tidy up
DROP TABLE dbo.Source;
Ответ 2
Я не верю, что вы можете напрямую удалить часть IDENTITY в столбце. Вероятнее всего, ваш лучший выбор:
- добавить другой столбец неидентификации в таблицу
- скопировать идентификационные значения в этот столбец
- удалить исходный столбец идентификаторов
- переименуйте новый столбец, чтобы заменить исходный столбец
Если столбец идентификатора является частью ключа или другого ограничения, вам нужно будет удалить эти ограничения и повторно создать их после завершения указанных операций.
Ответ 3
Вы можете добавить столбец в таблицу, которая не является столбцом идентификации, скопировать данные, удалить исходный столбец и переименовать новый столбец в старый столбец и воссоздать индексы.
Здесь - ссылка, показывающая пример. Все еще не простой вариант, но он, безусловно, лучше, чем 5231 строки.