Добавление идентификатора в существующий столбец - PullRequest
398 голосов
/ 26 июня 2009

Мне нужно изменить первичный ключ таблицы на столбец идентификаторов, и в таблице уже есть ряд строк.

У меня есть скрипт для очистки идентификаторов, чтобы они были последовательными, начиная с 1, отлично работает на моей тестовой базе данных.

Какая команда SQL изменяет столбец, чтобы иметь свойство идентификации?

Ответы [ 19 ]

2 голосов
/ 27 февраля 2019

Если вы используете Visual Studio 2017 +

  1. В обозревателе объектов сервера щелкните правой кнопкой мыши таблицу и выберите «просмотреть код»
  2. Добавьте модификатор "IDENTITY" в ваш столбец
  3. Обновление

Это все сделает за вас.

2 голосов
/ 31 июля 2017

Чтобы изменить свойства идентификатора для столбца:

  • В обозревателе серверов щелкните правой кнопкой мыши таблицу с идентификационными свойствами, которые вы хотите изменить, и выберите Открыть определение таблицы. Таблица открывается в конструкторе таблиц.
  • Снимите флажок «Разрешить пустые значения» для столбца, который вы хотите изменить.
  • На вкладке Свойства столбца разверните свойство Спецификация идентификации.
  • Щелкните ячейку сетки для дочернего свойства Is Identity и выберите Да в раскрывающемся списке.
  • Введите значение в ячейку Identity Seed. Это значение будет присвоено первой строке таблицы. Значение 1 будет присвоено по умолчанию.

Вот и все, и у меня это сработало

2 голосов
/ 12 июня 2017

Щелкните правой кнопкой мыши имя таблицы в обозревателе объектов. Вы получите несколько вариантов. Нажмите на «Дизайн». Новая таблица будет открыта для этой таблицы. Вы можете добавить ограничение Identity здесь, в «Свойства столбца».

2 голосов
/ 26 июня 2009

К сожалению, его нет; свойство IDENTITY принадлежит таблице, а не столбцу.

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

См. здесь для подробного описания счета.

1 голос
/ 26 апреля 2017

Согласно моему нынешнему состоянию, я придерживаюсь этого подхода. Я хочу присвоить первичную таблицу идентификаторам после вставки данных с помощью сценария.

Поскольку я хочу добавить идентификатор, чтобы он всегда начинался с 1 до конца количества записей, которое я хочу.

--first drop column and add with identity
ALTER TABLE dbo.tblProductPriceList drop column ID 
ALTER TABLE dbo.tblProductPriceList add ID INT IDENTITY(1,1)

--then add primary key to that column (exist option you can ignore)
IF  NOT EXISTS (SELECT * FROM sys.key_constraints  WHERE object_id = OBJECT_ID(N'[dbo].[PK_tblProductPriceList]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblProductPriceList]'))
    ALTER TABLE [tblProductPriceList] ADD PRIMARY KEY (id)
GO

Это создаст тот же столбец первичного ключа с идентификатором

Я использовал эти ссылки: https://blog.sqlauthority.com/2014/10/11/sql-server-add-auto-incremental-identity-column-to-table-after-creating-table/

Добавление первичного ключа в существующую таблицу

1 голос
/ 26 сентября 2011

Если исходный постер действительно хотел установить для таблицы существующий столбец равным PRIMARY KEY и фактически не нуждался в том, чтобы столбец был столбцом IDENTITY (две разные вещи), то это можно сделать с помощью t. -SQL с:

ALTER TABLE [YourTableName]
ADD CONSTRAINT [ColumnToSetAsPrimaryKey] PRIMARY KEY ([ColumnToSetAsPrimaryKey])

Обратите внимание на круглые скобки вокруг имени столбца после опции PRIMARY KEY.

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

0 голосов
/ 27 октября 2014

генерирует скрипт для всех таблиц с первичным ключом = bigint, у которых нет набора идентификаторов; это вернет список сгенерированных скриптов с каждой таблицей;

SET NOCOUNT ON;

declare @sql table(s varchar(max), id int identity)

DECLARE @table_name nvarchar(max),
        @table_schema nvarchar(max);

DECLARE vendor_cursor CURSOR FOR 
SELECT
  t.name, s.name
FROM sys.schemas AS s
INNER JOIN sys.tables AS t
  ON s.[schema_id] = t.[schema_id]
WHERE EXISTS (
    SELECT
    [c].[name]
    from sys.columns [c]
    join sys.types [y] on [y].system_type_id = [c].system_type_id
    where [c].[object_id] = [t].[object_id] and [y].name = 'bigint' and [c].[column_id] = 1
) and NOT EXISTS 
(
  SELECT 1 FROM sys.identity_columns
    WHERE [object_id] = t.[object_id]
) and exists (
    select 1 from sys.indexes as [i] 
    inner join sys.index_columns as [ic]  ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
    where object_name([ic].[object_id]) = [t].[name]
)
OPEN vendor_cursor

FETCH NEXT FROM vendor_cursor 
INTO @table_name, @table_schema

WHILE @@FETCH_STATUS = 0
BEGIN

DELETE FROM @sql

declare @pkname varchar(100),
    @pkcol nvarchar(100)

SELECT  top 1
        @pkname = i.name,
        @pkcol = COL_NAME(ic.OBJECT_ID,ic.column_id)
FROM    sys.indexes AS [i]
INNER JOIN sys.index_columns AS [ic] ON  i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
WHERE   i.is_primary_key = 1 and OBJECT_NAME(ic.OBJECT_ID) = @table_name

declare @q nvarchar(max) = 'SELECT  '+@pkcol+' FROM ['+@table_schema+'].['+@table_name+'] ORDER BY '+@pkcol+' DESC'

DECLARE @ident_seed nvarchar(max) -- Change this to the datatype that you are after
SET @q = REPLACE(@q, 'SELECT', 'SELECT TOP 1 @output = ')
EXEC sp_executeSql @q, N'@output bigint OUTPUT', @ident_seed OUTPUT

insert into  @sql(s) values ('BEGIN TRANSACTION')
insert into  @sql(s) values ('BEGIN TRY')

-- create statement
insert into  @sql(s) values ('create table ['+@table_schema+'].[' + @table_name + '_Temp] (')

-- column list
insert into @sql(s) 
select 
    '  ['+[c].[name]+'] ' +
    y.name + 

    (case when [y].[name] like '%varchar' then
    coalesce('('+(case when ([c].[max_length] < 0 or [c].[max_length] >= 1024) then 'max' else cast([c].max_length as varchar) end)+')','')
    else '' end)

     + ' ' +
    case when [c].name = @pkcol then 'IDENTITY(' +COALESCE(@ident_seed, '1')+',1)' else '' end + ' ' +
    ( case when c.is_nullable = 0 then 'NOT ' else '' end ) + 'NULL ' + 
    coalesce('DEFAULT ('+(
        REPLACE(
            REPLACE(
                LTrim(
                    RTrim(
                        REPLACE(
                            REPLACE(
                                REPLACE(
                                    REPLACE(
                                        LTrim(
                                            RTrim(
                                                REPLACE(
                                                    REPLACE(
                                                        object_definition([c].default_object_id)
                                                    ,' ','~')
                                                ,')',' ')
                                            )
                                        )
                                    ,' ','*')
                                ,'~',' ')
                            ,' ','~')
                        ,'(',' ')
                    )
                )
            ,' ','*')
        ,'~',' ')
    ) +
    case when object_definition([c].default_object_id) like '%get%date%' then '()' else '' end
    +
    ')','') + ','
 from sys.columns c
 JOIN sys.types y ON y.system_type_id = c.system_type_id
  where OBJECT_NAME(c.[object_id]) = @table_name and [y].name != 'sysname'
 order by [c].column_id


 update @sql set s=left(s,len(s)-1) where id=@@identity

-- closing bracket
insert into @sql(s) values( ')' )

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] ON')

declare @cols nvarchar(max)
SELECT @cols = STUFF(
    (
        select ',['+c.name+']'
        from sys.columns c
        JOIN sys.types y ON y.system_type_id = c.system_type_id
        where c.[object_id] = OBJECT_ID(@table_name)
        and [y].name != 'sysname'
        and [y].name != 'timestamp'
        order by [c].column_id
        FOR XML PATH ('')
     )
    , 1, 1, '')

insert into @sql(s) values( 'IF EXISTS(SELECT * FROM ['+@table_schema+'].['+@table_name+'])')
insert into @sql(s) values( 'EXEC(''INSERT INTO ['+@table_schema+'].['+@table_name+'_Temp] ('+@cols+')')
insert into @sql(s) values( 'SELECT '+@cols+' FROM ['+@table_schema+'].['+@table_name+']'')')

insert into @sql(s) values( 'SET IDENTITY_INSERT ['+@table_schema+'].['+@table_name+'_Temp] OFF')


insert into @sql(s) values( 'DROP TABLE ['+@table_schema+'].['+@table_name+']')

insert into @sql(s) values( 'EXECUTE sp_rename N''['+@table_schema+'].['+@table_name+'_Temp]'', N'''+@table_name+''', ''OBJECT''')

if ( @pkname is not null ) begin
    insert into @sql(s) values('ALTER TABLE ['+@table_schema+'].['+@table_name+'] ADD CONSTRAINT ['+@pkname+'] PRIMARY KEY CLUSTERED (')
    insert into @sql(s)
        select '  ['+COLUMN_NAME+'] ASC,' from information_schema.key_column_usage
        where constraint_name = @pkname
        GROUP BY COLUMN_NAME, ordinal_position
        order by ordinal_position

    -- remove trailing comma
    update @sql set s=left(s,len(s)-1) where id=@@identity
    insert into @sql(s) values ('  )')
end

insert into  @sql(s) values ('--Run your Statements')
insert into  @sql(s) values ('COMMIT TRANSACTION')
insert into  @sql(s) values ('END TRY')
insert into  @sql(s) values ('BEGIN CATCH')
insert into  @sql(s) values ('        ROLLBACK TRANSACTION')
insert into  @sql(s) values ('        DECLARE @Msg NVARCHAR(MAX)  ')
insert into  @sql(s) values ('        SELECT @Msg=ERROR_MESSAGE() ')
insert into  @sql(s) values ('        RAISERROR(''Error Occured: %s'', 20, 101,@msg) WITH LOG')
insert into  @sql(s) values ('END CATCH')

declare @fqry nvarchar(max)

-- result!
SELECT @fqry = (select char(10) + s from @sql order by id FOR XML PATH (''))


SELECT @table_name as [Table_Name], @fqry as [Generated_Query]
PRINT 'Table: '+@table_name
EXEC sp_executeSql @fqry

    FETCH NEXT FROM vendor_cursor 
    INTO @table_name, @table_schema
END 
CLOSE vendor_cursor;
DEALLOCATE vendor_cursor;
0 голосов
/ 19 апреля 2014

В основном есть четыре логических шага.

  1. Создать новый столбец идентификации. Включите вставку идентификатора для этого нового столбца.

  2. Вставьте данные из исходного столбца (столбца, который вы хотите преобразовать в удостоверение) в этот новый столбец.

  3. Отключить идентификатор вставки для нового столбца.

  4. Удалите исходный столбец и переименуйте новый столбец в имя исходного столбца.

Могут быть некоторые сложности, например работа на нескольких серверах и т. Д.

Пожалуйста, обратитесь к следующей статье за ​​шагами (используя ssms & T-sql). Эти шаги предназначены для новичков с меньшим контролем T-SQL.

http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx

0 голосов
/ 26 июня 2009

Я не верю, что вы можете изменить существующий столбец на столбец идентификаторов, используя tsql. Однако это можно сделать с помощью представления конструктора Enterprise Manager.

В качестве альтернативы вы можете создать новую строку в качестве столбца идентификаторов, удалить старый столбец, а затем переименовать новый столбец.

ALTER TABLE FooTable
ADD BarColumn INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY CLUSTERED
...