ALTER COLUMN & ldquo; IDENTITY & rdquo; для SQL Server [дубликат]

Предположим, что у вас есть следующий код

fruits = ("apples", "bananas", "loganberries")

def eat(food=fruits):
    ...

Когда я вижу декларацию о еде, наименее удивительной является мысль, что если первый параметр не указан, он будет равен tuple ("apples", "bananas", "loganberries")

Однако, предположим позже в коде, я делаю что-то вроде

def some_random_function():
    global fruits
    fruits = ("blueberries", "mangos")

, тогда, если параметры по умолчанию были связаны с выполнением функции, а не с объявлением функции, тогда я бы удивляйтесь (очень плохо), чтобы обнаружить, что фрукты были изменены. Это было бы более удивительно ИМО, чем обнаружение того, что ваша функция foo, указанная выше, мутировала список.

Реальная проблема заключается в изменяемых переменных, и все языки имеют определенную проблему. Возникает вопрос: предположим, что в Java у меня есть следующий код:

StringBuffer s = new StringBuffer("Hello World!");
Map<StringBuffer,Integer> counts = new HashMap<StringBuffer,Integer>();
counts.put(s, 5);
s.append("!!!!");
System.out.println( counts.get(s) );  // does this work?

Теперь, использует ли моя карта значение ключа StringBuffer, когда оно было помещено на карту, или оно хранит ключ по ссылке? В любом случае, кто-то удивлен; либо человек, который попытался получить объект из Map, используя значение, идентичное тому, с которым он положил его, или человек, который, похоже, не может получить свой объект, даже если ключ, который они используют, буквально тот же объект, который использовался для размещения его на карте (на самом деле Python не позволяет использовать его изменяемые встроенные типы данных в качестве словарных клавиш).

Ваш пример хороший случая, когда новички Python будут удивлены и укушены. Но я бы сказал, что если бы мы «исправили» это, тогда это создало бы другую ситуацию, в которой они были бы укушены, и это было бы еще менее интуитивным. Более того, это всегда имеет место при работе с изменяемыми переменными; вы всегда сталкиваетесь с ситуациями, когда кто-то может интуитивно ожидать одно или наоборот поведения в зависимости от того, какой код они пишут.

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

358
задан John Saunders 23 August 2011 в 01:15
поделиться

19 ответов

Здесь описано крутое решение: SQL SERVER - добавление или удаление свойства идентификатора в столбце

Короче отредактируйте вручную таблицу в SQL Manager, переключите идентификатор, НЕ SAVE, просто покажите сценарий, который будет создан для изменений, скопируйте его и используйте позже.

Это огромная экономия времени, потому что он (скрипт) содержит все внешние ключи, индексы и т. Д. связанные с таблицей, которую вы меняете. Напиши это вручную ... Не дай бог.

384
ответ дан aledpardo 20 August 2018 в 14:11
поделиться
  • 1
    Если данные таблицы малы, этот параметр работает gret. Если таблица большая, есть еще один вариант, который я предпочитаю: используйте ALTER TABLE ... SWITCH, чтобы заменить схему таблицы другой версией столбцом IDENTITY, но в противном случае идентичной схемой. Преимущество подхода ALTER TABLE .... SWITCH заключается в том, что он быстро завершается (менее 5 секунд для таблицы с миллиардной строкой), поскольку данные таблицы не нужно копировать или изменять. Однако есть оговорки и ограничения. Подробнее см. Мой ответ ниже. – Justin Grant 13 November 2009 в 18:56
  • 2
    @Justin Grat: Очень интересная альтернатива и тот, который я не рассматривал! Причина этого в том, что IDENTITY - это свойство столбца, а не тип данных, поэтому метод SWITCH проверяет схемы между двумя таблицами (старыми и новыми) как идентифицируемые независимо от разницы IDENTITY. Спасибо, что поделился! – John Sansom 15 November 2009 в 13:09
  • 3
    это решение, которое я использовал - SSMS генерирует T-SQL для внесения изменений ... он делает это, создавая новую временную таблицу того же дизайна схемы, затем копируя все строки в нее, удаляя исходный код и переименование , может занять немного времени, чтобы работать полностью, но он отлично работал. – mdelvecchio 6 July 2014 в 20:44
  • 4
    Я не думаю, что Pinal Dave на самом деле говорит, что вам нужно запустить сценарий, который вы создаете, это просто показать, что делает изменение через пользовательский интерфейс для вас ... – Zack 9 July 2015 в 15:47
  • 5
    Эта возможность сценариев в SSMS (об изменении определения таблицы) на самом деле является единственным правильным средством при документировании многораздельной таблицы. Наиболее подходящая локация «задача» - & gt; «таблица скриптов» всегда забывает сценарий функции разбиения! – Martijn van der Jagt 27 July 2015 в 16:27
  • 6
    Если у вас мало данных, тогда «создание таблицы» может быть достигнуто путем генерации сценария из SSMS. Щелкните правой кнопкой мыши таблицу & gt; Таблица Scrip как & gt; Создайте ТАБЛИЦУ до & gt; (новый редактор запросов?). Затем отбросьте его, и внутри этого скрипта вы можете добавить часть IDENTITY(1, 1) в столбец первичного ключа – goamn 8 June 2017 в 05:05
  • 7
    Можно также использовать SSMS для обеспечения этого. Перейдите в раздел Инструменты & gt; Опции & gt; Проектировщики & GT; Отменить проверку и «Запретить сохранение изменений, требующих повторного создания таблицы». Кстати, это не рекомендуется для довольно больших таблиц. – Zafar 7 May 2018 в 14:17
  • 8
    В PostgreSQL вы можете добавить идентификатор в существующий целочисленный столбец с командой: alter table {table_name} alter column {column_name} добавить сгенерированную всегда как идентификатор (перезапустить с {числом}); – Andrew Mackie 17 August 2018 в 00:25
394
ответ дан aledpardo 31 October 2018 в 10:44
поделиться

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

Как я хочу добавить идентификатор, поэтому он всегда начинается с 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-create-table /

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

4
ответ дан Community 20 August 2018 в 14:11
поделиться

Как я понял в обычных случаях, мы создаем таблицу с основным ключом, которая имеет свойство Identity. Так что переименовать или удалить столбец, связанный с ограничением первичного ключа, не будет возможным, поскольку правила ограничений проверяют структуру столбцов. Для этого мы должны обработать некоторые шаги следующим образом: предположим, что TableName = 'Employee' и ColumnName = 'EmployeeId' 1. Добавьте новый столбец «EmployeeId_new» в таблицу «Employee». ALTER TABLE Employee ADD EmployeeId_new INT IDENTITY ( 1,1)

  1. Теперь удалите столбец «EmployeeId» из таблицы «Employee». ALTER TABLE Employee DROP COLUMN EmployeeId
  2. Это вызовет ошибку из-за того, что правила ограничения основного ключа применимы и проверки структуры столбцов. * ### ' Msg 5074, уровень 16, состояние 1, строка 1 Объект [PK_dbo.Employee] зависит от colmn [EmployeeId].' ###
  3. So мы должны сначала удалить ограничение первичного ключа из таблицы «Сотрудник», тогда мы можем удалить столбец ALTER TABLE. Ограничение DROP сотрудника [PK_dbo.Employee]
  4. Теперь мы можем удалить столбец «EmployeeId» из «Employee» ', как на предыдущем шаге, где мы получили ошибку ALTER TABLE Employee DROP COLUMN EmployeeId
  5. Теперь Столбец «EmployeeId» удален из таблицы Итак, мы переименуем новый добавленный новый столбец «EmployeeId_new» с «EmployeeId» sp_rename 'Employee.EmployeeId', 'EmployeeId_new', 'COLUMN'
  6. Чтобы изменить таблицу в той же форме, что и она, нам нужно добавить ограничение первичного ключа для столбца «EmployeeId». ALTER TABLE Employee add constraint [PK_dbo.Employee] первичный ключ (EmployeeId)

8. Теперь таблица «Сотрудник» с «EmployeeId» изменена для правил Identity вместе с существующим ограничением первичного ключа

4
ответ дан eFarzad 20 August 2018 в 14:11
поделиться

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

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

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

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

1
ответ дан Hans Olsson 20 August 2018 в 14:11
поделиться

Принимаемый ответ неверен: вы можете изменить существующий столбец как идентификатор, если он не содержит никаких нулевых значений. После изменения семя идентичности начнется с max (column) + 1.

Итак, что вам действительно нужно сделать в первую очередь, это указать значения для всех нулей.

3
ответ дан Jacob 20 August 2018 в 14:11
поделиться

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

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

См. здесь для учетной записи «удар по удалению».

2
ответ дан Jeremy Smyth 20 August 2018 в 14:11
поделиться

В SQL 2005 и выше существует трюк для решения этой проблемы без изменения страниц данных таблицы. Это важно для больших таблиц, где касание каждой страницы данных может занимать минуты или часы. Трюк также работает, даже если столбец идентификатора является первичным ключом, является частью кластерного или некластеризованного индекса или других ошибок, которые могут отключить более простое решение «добавить / удалить / переименовать столбец».

Вот трюк: вы можете использовать инструкцию SQL Server ALTER TABLE ... SWITCH для изменения схемы таблицы без изменения данных, то есть вы можете заменить таблицу на IDENTITY с идентичной схемой таблицы, но без столбца IDENTITY. Тот же трюк работает, чтобы добавить IDENTITY в существующий столбец.

Обычно ALTER TABLE ... SWITCH используется для эффективной замены полного раздела в многораздельной таблице новым, пустой раздел. Но он также может использоваться и в несегментированных таблицах.

Я использовал этот трюк, чтобы преобразовать менее чем за 5 секунд столбец таблицы из 2,5 миллиардов строк из IDENTITY в не- IDENTITY (для запуска многочасового запроса, чей план запроса работал лучше для столбцов без идентификатора), а затем восстановил параметр IDENTITY, снова менее чем за 5 секунд.

Вот пример кода того, как оно работает.

 CREATE TABLE Test
 (
   id int identity(1,1),
   somecolumn varchar(10)
 );

 INSERT INTO Test VALUES ('Hello');
 INSERT INTO Test VALUES ('World');

 -- copy the table. use same schema, but no identity
 CREATE TABLE Test2
 (
   id int NOT NULL,
   somecolumn varchar(10)
 );

 ALTER TABLE Test SWITCH TO Test2;

 -- drop the original (now empty) table
 DROP TABLE Test;

 -- rename new table to old table's name
 EXEC sp_rename 'Test2','Test';

 -- update the identity seed
 DBCC CHECKIDENT('Test');

 -- see same records
 SELECT * FROM Test; 

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

  • Насколько мне известно, идентификация - это единственное, что можно изменить в столбцах таблицы с помощью этого метода. Добавление / удаление столбцов, изменение нулевой и т. Д. Недопустимы.
  • Вам нужно будет отбросить ключи foriegn до того, как вы сделаете переключатель, и восстановите их после.
  • То же самое для функций SCHEMABINDING, просмотров и т. д.
  • new Табличные индексы должны точно соответствовать (одни и те же столбцы, один и тот же порядок и т. д.)
  • Старые и новые таблицы должны быть в одной и той же файловой группе.
  • Работает только на SQL Server 2005 или более поздней версии
  • Ранее я считал, что этот трюк работает только на выпусках Enterprise или Developer SQL Server (поскольку разделы поддерживаются только в версиях Enterprise и Developer), но Мейсон Г. Жвити в своем комментарии ниже говорит, что он также работает также в SQL Standard Edition. Я предполагаю, что это означает, что ограничение на Enterprise или Developer не распространяется на ALTER TABLE ... SWITCH.

В TechNet есть хорошая статья , в которой подробно описаны требования выше.

UPDATE - У Eric Wu был комментарий ниже, который добавляет важную информацию об этом решении. Копируем его здесь, чтобы удостовериться, что он получает больше внимания:

Здесь есть еще одна оговорка, о которой стоит упомянуть. Несмотря на то, что новая таблица с радостью получит данные из старой таблицы, а все новые строки будут вставлены после шаблона идентификации, они будут начинаться с 1 и потенциально прерываться, если указанный столбец является первичным ключом. Рассмотрите возможность запуска DBCC CHECKIDENT('<newTableName>') сразу после переключения. См. msdn.microsoft.com/en-us/library/ms176057.aspx для получения дополнительной информации.

Если таблица активно расширяется новыми строками (что означает у вас мало времени, если есть время простоя между добавлением IDENTITY и добавлением новых строк, вместо DBCC CHECKIDENT вы захотите вручную установить начальное значение идентификатора в новой схеме таблицы больше, чем самый большой существующий идентификатор в таблице , например IDENTITY (2435457, 1). Возможно, вы сможете включить в транзакцию ALTER TABLE...SWITCH и DBCC CHECKIDENT (или нет - не проверили это), но похоже, что установка начального значения вручную будет проще и безопаснее.

Очевидно, что если новые строки не добавляются в таблицу (или они добавляются только иногда, как ежедневный процесс ETL), то этого состояния гонки не произойдет, так что DBCC CHECKIDENT в порядке.

169
ответ дан Justin Grant 20 August 2018 в 14:11
поделиться
  • 1
    FYI, похоже, также работает над стандартной версией SQL 2008 R2. Возможно, они включили эту функцию так же, как теперь они позволили включить сжатие резервной копии. – Mason G. Zhwiti 13 October 2011 в 17:04
  • 2
    Мейсон - замечательное наблюдение! Я обновил свой ответ соответственно. Я предположил, что, поскольку разделы не поддерживаются в стандарте SQL, что ALTER TABLE ... SWITCH не поддерживается. Но, учитывая, что вы можете использовать эту команду для несегментированных таблиц, имеет смысл, что вы также можете запустить ее в Standard Edition. Спасибо за исправление. – Justin Grant 20 October 2011 в 02:08
  • 3
    @jbatista - вопрос OP заявил, что у него уже был первичный ключ на столе, и он уже мог обеспечить правильные значения, но он просто хотел изменить его как столбец IDENTITY. Мой ответ выше сосредоточен на узком прецеденте: как добавить IDENTITY в столбец без фактического изменения каких-либо данных. Подход, который я документирую выше, - это огромная экономия времени для больших таблиц. Если вам нужно изменить данные, вам понадобятся другие решения. – Justin Grant 24 October 2014 в 23:00
  • 4
    Здесь есть еще одна оговорка, о которой стоит упомянуть. Несмотря на то, что новая таблица с радостью получит данные из старой таблицы, а все новые строки будут вставлены после шаблона идентификации, они начнутся с 1 и потенциально сломаются, если указанный столбец является первичным ключом. Попытайтесь запустить DBCC CHECKIDENT('<newTableName>') сразу после переключения. Дополнительную информацию см. В msdn.microsoft.com/en-us/library/ms176057.aspx . – Eric Wu 8 August 2016 в 15:13
  • 5
    Это отличный ответ! Также обратите внимание, что значение столбца должно быть одинаковым. Поэтому, если вам нужно изменить значение столбца для столбца, вам нужно будет сделать это на более позднем этапе. То же самое касается ограничений PK. Я также изменяю значение идентификатора в создании таблицы для соответствия текущему максимуму: IDENTITY (maxID + 1, 1) – Philippe 16 August 2016 в 20:18

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

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

Вот и все, что сработало для меня

2
ответ дан Ken.Fukizi 20 August 2018 в 14:11
поделиться

генерирует скрипт для всех таблиц с первичным ключом = 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
ответ дан Kyle Gibbar 20 August 2018 в 14:11
поделиться

Вы не можете изменить столбец, который будет столбцом IDENTITY. Что вам нужно сделать, это создать новый столбец, который определяется как идентификатор из get-go, затем удалить старый столбец и переименовать новый в старое имя.

ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1)

ALTER TABLE (yourTable) DROP COLUMN OldColumnName

EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN'

Марк

59
ответ дан marc_s 20 August 2018 в 14:11
поделиться
  • 1
    Это не работает, если этот столбец является ограничением – Constantine Gladky 28 May 2013 в 14:45
  • 2
    Либо параметр \ @objname неоднозначен, либо заявленный \ @objtype (COLUMN) ошибочен. – Jenny O'Reilly 2 October 2013 в 09:50
  • 3
    @ JennyO'Reilly: поставьте это в отдельный вопрос, и покажите нам полную команду, которую вы используете! – marc_s 2 October 2013 в 09:51
  • 4
    Это была процедура sp_rename, которая терпела неудачу. Я нашел решение в stackoverflow, выполнив поиск текста ошибки. Кажется, что это строгое правило синтаксиса с скобками, хотя моя таблица не имеет специальных символов в его имени. – Jenny O'Reilly 3 October 2013 в 17:21
  • 5
    или это может быть как: «ALTER TABLE (yourTable) DROP COLUMN OldColumnName» и «ALTER TABLE (yourTable) ADD OldColumnName INT IDENTITY (1,1)», почему переименовать: p – R K Sharma 9 January 2015 в 11:22

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

Если мы используем SQL Server Management Studio, чтобы избавиться от значения идентификатора в столбце «id» создается новая временная таблица, данные перемещаются во временную таблицу, старая таблица удаляется и новая таблица переименовывается.

Используйте Management Studio, чтобы внести изменения, а затем щелкните правой кнопкой мыши в конструкторе и выберите «Сгенерировать сценарий изменений».

Вы увидите, что это то, что делает SQL-сервер в фоновом режиме.

3
ответ дан Raj 20 August 2018 в 14:11
поделиться

Простое объяснение

Переименуйте существующий столбец, используя sp_RENAME

EXEC sp_RENAME 'Table_Name.Existing_ColumnName', 'New_ColumnName', 'COLUMN'

Пример для переименования :

Существующий столбец UserID переименован в OldUserID

EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN'

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

ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1)

Пример для Set Primary key

Новое имя созданного столбца - UserID

ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1)

, затем Drop the Renamed Column

ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName

Пример для Drop переименован столбец

ALTER TABLE Users DROP COLUMN OldUserID

Теперь мы добавили ключ доступа и идентификатор к существующему столбцу таблицы.

5
ответ дан Sathish Chelladurai 20 August 2018 в 14:11
поделиться

В принципе существует четыре логических шага.

  1. Создайте новый столбец Identity. Включите Insert Identity для этого нового столбца.
  2. Вставьте данные из столбца источника (столбец, который вы хотите преобразовать в Identity) в этот новый столбец.
  3. Отключите Insert Identity для нового столбца.
  4. Оставьте исходный столбец & amp; переименуйте новый столбец в имя исходного столбца.

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

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

http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert- INT-столбца к идентичности-в-MS-SQL-server.aspx

0
ответ дан Shivalik Chakravarty 20 August 2018 в 14:11
поделиться

вы не можете этого сделать, вам нужно добавить другой столбец, удалить исходный столбец и переименовать новый столбец или создать новую таблицу, скопировать данные и удалить старую таблицу, а затем переименовать новую таблицу к старой таблице

, если вы используете SSMS и устанавливаете свойство identity в ON в конструкторе, это то, что SQL Server делает за кулисами. Поэтому, если у вас есть таблица с именем [user], это происходит, если вы делаете UserID и identity

BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION

GO

GO
CREATE TABLE dbo.Tmp_User
    (
    UserID int NOT NULL IDENTITY (1, 1),
    LastName varchar(50) NOT NULL,
    FirstName varchar(50) NOT NULL,
    MiddleInitial char(1) NULL

    )  ON [PRIMARY]
GO

SET IDENTITY_INSERT dbo.Tmp_User ON
GO
IF EXISTS(SELECT * FROM dbo.[User])
 EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial)
    SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX')
GO
SET IDENTITY_INSERT dbo.Tmp_User OFF
GO

GO
DROP TABLE dbo.[User]
GO
EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT'
GO
ALTER TABLE dbo.[User] ADD CONSTRAINT
    PK_User PRIMARY KEY CLUSTERED 
    (
    UserID
    ) ON [PRIMARY]

GO
COMMIT

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

3
ответ дан SQLMenace 20 August 2018 в 14:11
поделиться

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

2
ответ дан vamsi_874 20 August 2018 в 14:11
поделиться

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

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

ALTER TABLE FooTable
ADD BarColumn INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY CLUSTERED
0
ответ дан William Edmondson 20 August 2018 в 14:11
поделиться
  • 1
    имейте в виду, что если вы сделаете это через SSMS / Enterprise Manager - вы будете создавать новую таблицу, копировать данные, отбрасывать старую таблицу и переименовывать новую. Это может быть довольно дорого, когда у вас большие столы ... – Scott Ivey 26 June 2009 в 15:00
4
ответ дан Community 31 October 2018 в 10:44
поделиться
4
ответ дан eFarzad 31 October 2018 в 10:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: