Удалить идентификатор из столбца таблицы

У нас есть таблица размером 5 ГБ (около 500 миллионов строк), и мы хотим удалить свойство идентификации в одном из столбцов, но когда мы пытаемся сделать это через SSMS - это время.

Можно ли это сделать через T-SQL?

Ответ 1

Вы не можете удалить спецификацию IDENTITY после ее установки.

Чтобы удалить весь столбец:

ALTER TABLE yourTable
DROP COLUMN yourCOlumn;

Информация о ALTER TABLE здесь

Если вам нужно сохранить данные, но удалите столбец IDENTITY, вам нужно будет:

  • Создать новый столбец
  • Перенос данных из существующего столбца IDENTITY в новый столбец
  • Отмените существующий столбец IDENTITY.
  • Переименуйте новый столбец в исходное имя столбца

Ответ 2

Это становится беспорядочным с ограничениями на внешние и первичные ключи, поэтому здесь есть несколько сценариев, которые помогут вам на вашем пути:

Сначала создайте дубликат столбца с временным именем:

alter table yourTable add tempId int NOT NULL default -1;
update yourTable set tempId = id;

Затем введите имя вашего основного ключа:

SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'yourTable';

Теперь попробуйте отбросить ограничение первичного ключа для вашего столбца:

ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;

Если у вас есть внешние ключи, он будет терпеть неудачу, поэтому, если это произойдет, уменьшите ограничения внешнего ключа. СОХРАНЯЙТЕ СЛЕДУЮЩИЕ ТАБЛИЦЫ, ВЫ ИСПОЛЬЗУЕТЕ ЭТО ДЛЯ ТАК, ЧТО ВЫ МОЖЕТЕ ДОЛЖНЫ ДОЛЖНЫ НАСТУПИТЬ СЛОЖНЫЕ ЗАДНИКИ!!!

SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'otherTable';
alter table otherTable drop constraint fk_otherTable_yourTable;
commit;
..

Как только все ограничения внешнего ключа будут удалены, вы сможете удалить ограничение PK, удалить этот столбец, переименовать свой столбец temp и добавить ограничение PK в этот столбец:

ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
alter table yourTable drop column id;
EXEC sp_rename 'yourTable.tempId', 'id', 'COLUMN';
ALTER TABLE yourTable ADD CONSTRAINT PK_yourTable_id PRIMARY KEY (id) 
commit;

Наконец, добавьте ограничения FK еще:

alter table otherTable add constraint fk_otherTable_yourTable foreign key (yourTable_id) references yourTable(id);
..

El Fin!

Ответ 3

Если вы хотите сделать это без добавления и заполнения нового столбца, без переупорядочения столбцов и с почти отсутствием времени простоя, потому что нет данные изменяются в таблице, позволяют сделать магию с помощью функций секционирования (но поскольку не используются разделы, вам не нужна версия Enterprise):

  • Удалите все внешние ключи, указывающие на эту таблицу.
  • Script таблицу, которая будет создана; переименовать все, например. "MyTable2", "MyIndex2" и т.д. Удалите спецификацию IDENTITY.
  • Теперь вы должны иметь две "идентичные" таблицы -ish, одну полную, другую пустую без IDENTITY.
  • Выполнить ALTER TABLE [Original] SWITCH TO [Original2]
  • Теперь ваша исходная таблица будет пустой, а новая будет иметь данные. Вы переключили метаданные для двух таблиц (мгновенно).
  • Отбросьте исходную (теперь пустую таблицу), exec sys.sp_rename, чтобы переименовать различные объекты схемы обратно в исходные имена, а затем вы можете воссоздать свои внешние ключи.

Например, данный:

CREATE TABLE Original
(
  Id INT IDENTITY PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value ON Original (Value);

INSERT INTO Original
SELECT 'abcd'
UNION ALL 
SELECT 'defg';

Вы можете сделать следующее:

--create new table with no IDENTITY
CREATE TABLE Original2
(
  Id INT PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value2 ON Original2 (Value);

--data before switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;

ALTER TABLE Original SWITCH TO Original2;

--data after switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;

--clean up
DROP TABLE Original;
EXEC sys.sp_rename 'Original2.IX_Original_Value2', 'IX_Original_Value', 'INDEX';
EXEC sys.sp_rename 'Original2', 'Original', 'OBJECT';


UPDATE Original
SET Id = Id + 1;

SELECT *
FROM Original;

Ответ 4

У меня была такая же проблема. 4 в SSMS вместо использования GUI, и это было очень быстро.

  • Создать новый столбец

    alter table users add newusernum int;

  • Скопировать значения по

    update users set newusernum=usernum;

  • Отбросить старый столбец

    alter table users drop column usernum;

  • Переименуйте новый столбец в имя старого столбца

    EXEC sp_RENAME 'users.newusernum' , 'usernum', 'COLUMN';

Ответ 5

После script удаляет поле Identity для столбца с именем 'Id'

Надеюсь, что это поможет.

BEGIN TRAN
BEGIN TRY
    EXEC sp_rename '[SomeTable].[Id]', 'OldId';

    ALTER TABLE [SomeTable] ADD Id int NULL

    EXEC ('UPDATE [SomeTable] SET Id = OldId')

    ALTER TABLE [SomeTable] NOCHECK CONSTRAINT ALL

    ALTER TABLE [SomeTable] DROP CONSTRAINT [PK_constraintName];
    ALTER TABLE [SomeTable] DROP COLUMN OldId
    ALTER TABLE [SomeTable] ALTER COLUMN [Id] INTEGER NOT NULL
    ALTER TABLE [SomeTable] ADD CONSTRAINT PK_JobInfo PRIMARY KEY (Id)

    ALTER TABLE [SomeTable] CHECK CONSTRAINT ALL

    COMMIT TRAN
END TRY
BEGIN CATCH
    ROLLBACK TRAN   
    SELECT ERROR_MESSAGE ()
END CATCH

Ответ 6

Код Bellow работает отлично, , когда мы не знаем имя столбца идентификации.

и хотите скопировать данные в новую таблицу темпа, например Invoice_DELETED. и в следующий раз мы используем: insert into Invoice_DELETED select * from Invoice, где...

SELECT t1.*
INTO Invoice_DELETED
FROM Invoice t1
LEFT JOIN Invoice ON 1 = 0
--WHERE t1.InvoiceID = @InvoiceID

Особая благодарность "Андрею М"

для более подробного объяснения см.: https://dba.stackexchange.com/a/138345/101038