установить идентичность в столбце - PullRequest
3 голосов
/ 03 марта 2011

Как я могу изменить таблицу и установить идентичность в столбце PK с помощью T-SQL?

спасибо за помощь

Ответы [ 6 ]

3 голосов
/ 23 мая 2011

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

И то, и другое может потребовать большого количества действий по блокировке и ведению журнала, что я всегда находил раздражающим, так как это изменение только метаданных и не должно вообще требовать прикосновения к страницам данных (действительно, можно обновить метаданные напрямую, запустив экземпляр в однопользовательском режиме и возиться с некоторыми столбцами в sys.syscolpars, но это недокументировано / не поддерживается.)

Однако обходной путь, опубликованный на этом элементе соединения , показывает полностью поддерживаемый способ преобразования этого в изменение метаданных только с помощью ALTER TABLE...SWITCH (credit SQLKiwi )

Пример кода.

Настройка тестовой таблицы без столбца identity.

CREATE TABLE dbo.tblFoo 
(
bar INT PRIMARY KEY,
filler CHAR(8000),
filler2 CHAR(49)
)


INSERT INTO dbo.tblFoo (bar)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM master..spt_values v1, master..spt_values v2

Измените его на столбец identity (более или менее мгновенный).

BEGIN TRY;
    BEGIN TRANSACTION;

    /*Using DBCC CHECKIDENT('dbo.tblFoo') is slow so use dynamic SQL to
      set the correct seed in the table definition instead*/
    DECLARE @TableScript nvarchar(max)
    SELECT @TableScript = 
    '
    CREATE TABLE dbo.Destination(
        bar INT IDENTITY(' + 
                     CAST(ISNULL(MAX(bar),0)+1 AS VARCHAR) + ',1)  PRIMARY KEY,
        filler CHAR(8000),
        filler2 CHAR(49)
        )

        ALTER TABLE dbo.tblFoo SWITCH TO dbo.Destination;
    '       
    FROM dbo.tblFoo
    WITH (TABLOCKX,HOLDLOCK)

    EXEC(@TableScript)


    DROP TABLE dbo.tblFoo;

    EXECUTE sp_rename N'dbo.Destination', N'tblFoo', 'OBJECT';


    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
    PRINT ERROR_MESSAGE();
END CATCH;

Проверьте результат.

INSERT INTO dbo.tblFoo (filler,filler2) 
OUTPUT inserted.*
VALUES ('foo','bar')

Придает

bar         filler    filler2
----------- --------- ---------
10001       foo       bar      

Очистить

DROP TABLE dbo.tblFoo
3 голосов
/ 03 марта 2011

Вы не можете изменить существующий столбец, чтобы иметь свойство IDENTITY - вы должны:

  • создать новую таблицу с той же структурой (но с установленной IDENTITY),
  • включить IDENTITY_INSERT для этой новой таблицы,
  • вставить строки из старой таблицы в новую таблицу,
  • отбросить старую таблицу, и,
  • переименуйте новую таблицу, чтобы иметь имя старой таблицы.

Если задействованы внешние ключи, их также необходимо исправить.

0 голосов
/ 11 марта 2016

Это ответ, который вы ищете?

DBCC CHECKIDENT( 
    'DBName.dbo.TableName'
    ,RESEED --[, new_reseed_value ]
)

Пример использования:

DBCC CHECKIDENT( 
    'DBName.dbo.TableName'
)

Проверка идентификационной информации: текущее значение идентификатора '1', текущее значение столбца '1211031236'. Выполнение DBCC завершено. Если DBCC напечатал сообщения об ошибках, обратитесь к системному администратору.

DBCC CHECKIDENT( 
    'DBName.dbo.TableName'
    ,RESEED --[, new_reseed_value ]
)

Проверка идентификационной информации: текущее значение идентификатора «1211031236», текущее значение столбца «1211031236». Выполнение DBCC завершено. Если DBCC напечатал сообщения об ошибках, обратитесь к системному администратору.

0 голосов
/ 03 марта 2011

Поскольку столбцы идентификаторов можно игнорировать только для insert, а не для update, вам понадобится промежуточная таблица. Вот пример:

create table TestTable (pk int constraint PK_TestTable primary key, 
    name varchar(30))
create table TestTable2 (pk int constraint PK_TestTable identity primary key, 
    name varchar(30))
set identity_insert TestTable2 on
insert TestTable2 (pk, name) select pk, name from TestTable
set identity_insert TestTable2 off
drop table TestTable
exec sp_rename 'TestTable2', 'TestTable'
0 голосов
/ 03 марта 2011

Вам нужно использовать команду ALTER TABLE - всегда сначала тестируйте в dev или pre-production!

Пример G кажется наиболее близким к вашему требованию:

CREATE TABLE dbo.doc_exe (column_aINT CONSTRAINT column_a_un UNIQUE);GO ALTER TABLE dbo.doc_exe ADD

- добавить столбец идентификатора PRIMARY KEY.column_b INT IDENTITY CONSTRAINT column_b_pk ПЕРВИЧНЫЙ КЛЮЧ,

См. http://msdn.microsoft.com/en-us/library/ms190273.aspx

0 голосов
/ 03 марта 2011

На самом деле, вы можете изменить IDENTITY для столбца. Пожалуйста, прочитайте эту статью http://www.sqlmag.com/article/tsql3/adding-the-identity-property-to-an-existing-column.aspx

Для этого потребуется намного больше кода, чем ALTER TABLE tab ALTER COLUMN col SET IDENTITY, хотя

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