Додавання ідентичності до наявного стовпця


445

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

У мене є сценарій очищення ідентифікаторів, щоб переконатися, що вони послідовні, починаючи з 1, добре працює на моїй тестовій базі даних.

Яка команда SQL для зміни стовпця, щоб мати властивість ідентичності?

Відповіді:


482

Ви не можете змінити наявні стовпці для ідентичності.

У вас є два варіанти,

  1. Створіть нову таблицю з ідентичністю та видаліть існуючу таблицю

  2. Створіть новий стовпець із ідентифікацією та скиньте наявний стовпець

Підхід 1. ( Нова таблиця ) Тут ви можете зберегти існуючі значення даних у новоствореному стовпчику ідентичності.

CREATE TABLE dbo.Tmp_Names
    (
      Id int NOT NULL
             IDENTITY(1, 1),
      Name varchar(50) NULL
    )
ON  [PRIMARY]
go

SET IDENTITY_INSERT dbo.Tmp_Names ON
go

IF EXISTS ( SELECT  *
            FROM    dbo.Names ) 
    INSERT  INTO dbo.Tmp_Names ( Id, Name )
            SELECT  Id,
                    Name
            FROM    dbo.Names TABLOCKX
go

SET IDENTITY_INSERT dbo.Tmp_Names OFF
go

DROP TABLE dbo.Names
go

Exec sp_rename 'Tmp_Names', 'Names'

Підхід 2 ( новий стовпець ) Ви не можете зберегти існуючі значення даних у новоствореному стовпчику ідентичності, стовпець ідентичності буде містити послідовність числа.

Alter Table Names
Add Id_new Int Identity(1, 1)
Go

Alter Table Names Drop Column ID
Go

Exec sp_rename 'Names.Id_new', 'ID', 'Column'

Докладнішу інформацію див. У наступній публікації форуму Microsoft SQL Server:

Як змінити стовпчик на ідентичність (1,1)


49
Якщо даних таблиці мало, цей параметр працює з точністю. Якщо таблиця велика, я вважаю за краще інший варіант: використовувати ALTER TABLE ... SWITCH для заміни схеми таблиці на іншу версію стовпцем Ідентичність, але в іншому випадку ідентичною схемою. Перевага підходу ALTER TABLE .... SWITCH полягає в тому, що він швидко завершується (менше 5 секунд для таблиці в мільярд рядків), оскільки жодних даних таблиці не потрібно копіювати чи змінювати. Однак є застереження та обмеження. Детальну інформацію див. У моїй відповіді нижче.
Джастін Грант

7
@Justin Grat: Дуже цікава альтернатива і та, яку я не розглядав! Причина цього працює в тому, що IDENTITY є властивістю стовпця, а не типом даних, тому метод SWITCH перевіряє схеми між двома таблицями (старою та новою) як ідентифіковані незалежно від різниці ІДЕНТИЧНОСТІ. Дякую, що поділились!
Джон Сансон

Якщо у вас не так багато даних, то "створення таблиці" можна досягти, створивши сценарій із SSMS. Клацніть правою кнопкою миші таблицю> Таблиця сценаріїв як> Створити таблицю для> (новий редактор запитів?). Потім киньте його, і всередині цього сценарію ви можете додати IDENTITY(1, 1)частину до стовпця первинного ключа
goamn

Можна також використовувати SSMS для цього. Перейдіть до Інструменти> Опції> Дизайнери> Зніміть прапорець "Запобігти збереженню змін, які потребують відновлення таблиці". До речі, це не рекомендується для досить великих таблиць.
Зафар

У PostgreSQL ви можете додати ідентичність до наявного цілого стовпця за допомогою команди: змінити таблицю {table_name} змінити стовпчик {column_name} додати генерований завжди як ідентичність (перезапустити з {number});
Ендрю Макі

209

У SQL 2005 і вище є хитрість вирішити цю проблему без зміни сторінок даних таблиці. Це важливо для великих таблиць, де торкання кожної сторінки даних може зайняти хвилини чи години. Трюк також працює, навіть якщо стовпець ідентичності є первинним ключем, є частиною кластерного або некластеризованого індексу або інших gotchas, які можуть відключити простіше рішення "додавання / видалення / перейменування стовпця".

Ось хитрість: ви можете використовувати ALTER TABLE ... SWITCH SQL Server для зміни схеми таблиці без зміни даних, тобто ви можете замінити таблицю на IDENTITY ідентичною схемою таблиці, але без стовпця IDENTITY. Цей же трюк працює на додавання ідентичності до вже наявного стовпця.

Зазвичай, АЛЕ ТАБЛИЦЯ ... ПЕРЕКЛЮЧАЙТЕ використовується для ефективної заміни повного розділу в таблиці, що розділяється, новим порожнім розділом. Але він може бути використаний і в нерозподілених таблицях.

Цей трюк я використав для менш ніж 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; 

Це, очевидно, більше пов'язане з рішеннями в інших відповідях, але якщо ваш стіл великий, це може бути реальною економією життя. Є кілька застережень:

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

Там є хороша стаття про TechNet, де детально описані вище вимоги.

ОНОВЛЕННЯ - Ерік Ву зауважив коментар нижче, який додає важливу інформацію про це рішення. Скопіюйте його сюди, щоб отримати більше уваги:

Тут є ще одне застереження, яке варто згадати. Незважаючи на те, що нова таблиця буде радісно отримувати дані зі старої таблиці, і всі нові рядки будуть вставлені згідно з ідентифікаційною схемою, вони почнуться з 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це добре.


5
Якщо моя пам'ять правильна, я отримав ідею з цієї статті: sqlservercentral.com/articles/T-SQL/61979
Джастін Грант

2
FYI, це, здається, працює і над стандартною версією SQL 2008 R2. Можливо, вони ввімкнули цю функцію так само, як тепер увімкнули можливість включення резервного стиснення.
Мейсон Жвіті

3
@jbatista - у запитанні ОП було вказано, що він вже мав первинний ключ на столі і вже міг забезпечити правильні значення, але він просто хотів змінити його на стовпець ІДЕНТИМИТЕТ. Моя відповідь вище зосереджена на вузькому випадку використання: як додати ІДЕНТИЧНІСТЬ до стовпця, не змінюючи фактично жодних даних. Підхід, який я документую вище, є величезною економією часу для великих таблиць. Якщо вам потрібно змінити дані, знадобиться використовувати інші рішення.
Джастін Грант

3
Тут є ще одне застереження, яке варто згадати. Якщо все-таки нова таблиця із задоволенням отримає дані зі старої таблиці, і всі нові рядки будуть вставлені згідно з ідентифікаційним шаблоном, вони почнуться з 1 і, можливо, розіб'ються, якщо зазначений стовпець є первинним ключем. Подумайте про запуск DBCC CHECKIDENT('<newTableName>')відразу після перемикання. Додаткову інформацію див. У msdn.microsoft.com/en-us/library/ms176057.aspx .
Ерік Ву

3
Це чудова відповідь! Також зауважте, що нульованість стовпців повинна бути однаковою. Тож якщо вам потрібно змінити нульовість стовпця, вам доведеться це зробити на наступному кроці. Те саме стосується обмежень ПК. Я також змінюю значення ідентичності у створенні таблиці, щоб відповідати поточному максимуму: IDENTITY (maxID + 1, 1)
Philippe

71

Ви не можете змінити стовпець, щоб він був стовпцем Ідентифікатор. Що вам потрібно зробити, це створити новий стовпець, який визначається як ІДЕНТИЧНІСТЬ з початку руху, потім скиньте старий стовпець і перейменуйте новий на старе ім'я.

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

ALTER TABLE (yourTable) DROP COLUMN OldColumnName

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

Марк


Або параметр \ @objname неоднозначний, або заявлений \ @objtype (COLUMN) неправильний.
Дженні О'Рейлі

1
@ JennyO'Reilly: поставте це окремим питанням і покажіть нам повну команду, яку ви використовуєте!
marc_s

2
Це була процедура невдалого імені sp_rename. Я знайшов рішення в stackoverflow, шукаючи текст помилки. Здається, це якесь суворе синтаксичне правило з дужками, хоча в моїй таблиці немає жодних спеціальних символів у його імені.
Jenny O'Reilly

1
або це могло б виглядати так: 'ALTER TABLE (yourTable) DROP COLUMN OldColumnName' та 'ALTER TABLE (yourTable) ДОДАТИ OldColumnName INT IDENTITY (1,1)', чому перейменуйте: p
RK Sharma

Марк, я спробував цю точну команду на величезному столі (~ 300млн рядків), але я зупинив процес через ~ 10 хв.
Наомі

14

Тут описано круте рішення: SQL SERVER - додавання та видалення властивості ідентичності в стовпці

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

Це величезна економія часу, оскільки вона (скрипт) містить усі зовнішні ключі, індекси тощо, пов'язані зі зміною таблиці. Писати це вручну ... Не дай Бог.


це рішення, яке я використовував - SSMS генерує T-SQL для внесення змін ... це робиться, створюючи нову тимчасову таблицю тієї ж конструкції схеми, потім копіюючи в неї всі рядки, видаляючи orig і перейменуючи . може зайняти трохи часу для повного запуску, але це спрацювало чудово.
mdelvecchio

Я не думаю, що Pinal Dave насправді говорить, що вам потрібно запустити створений вами сценарій, це просто показати, що робить зміни через інтерфейс для вас ...
Zack

Цей сценарій сценарію в SSMS (про зміну визначення таблиці) насправді є єдиним правильним засобом при документуванні розділеної таблиці. Найбільш підходяще місце розташування "завдання" -> "таблиця скриптів" завжди забудьте прописати функцію розділення!
Martijn van der Jagt

1
Може бути комусь корисним. Щоб отримати сценарій зміни після змін. Клацніть правою кнопкою миші таблицю в режимі дизайну на SSMS та виберіть опцію "Створити сценарій зміни" та збережіть сценарій на локальному диску
Vijai

11

Подумайте використовувати SEQUENCE замість ідентичності .

На сервері IN sql 2014 (я не знаю про нижчі версії) ви можете це зробити просто, використовуючи послідовність.

CREATE SEQUENCE  sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1;

ALTER TABLE table_name ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name

Звідси: Послідовність як значення за замовчуванням для стовпця


6

Просте пояснення

Перейменуйте існуючий стовпець за допомогою sp_RENAME

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

Приклад для перейменування:

Існуючий стовпець UserID перейменовано на OldUserID

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

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

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

Приклад для встановлення первинного ключа

Нова створена назва стовпця - UserID

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

потім відкиньте перейменовану колону

ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName

Приклад для скидання перейменованого стовпця

ALTER TABLE Users DROP COLUMN OldUserID

Тепер ми додаємо первинну клавішу та особистість до наявного стовпця таблиці.


5

Я розробник Java, який трапився в команду без DBA, і там, де як розробник, я не можу отримати права DBA. Мені було доручено перемістити всю схему між двома базами даних, тому, не маючи DBA, мені довелося це робити і виконувати сценарії, не маючи можливості користуватися графічним інтерфейсом у SQL Server 2008, оскільки у мене не було прав адміністратора.

Все було переміщено без проблем, проте, запустивши збережену процедуру на новому schema.table, я виявив, що втратив поле ідентичності в таблиці. Я двічі перевірив сценарій, який створив таблицю, і він там був, однак, SQL Server не отримав цього, коли я запустив сценарій. Пізніше мені DBA повідомили, що він бачив цю саму проблему і раніше.

У будь-якому випадку, для SQL Server 2008 це кроки, які я вжив, щоб вирішити це питання, і вони спрацювали, тому я публікую це тут, сподіваючись, що це допоможе комусь. Це те, що я зробив, коли мав залежності від ФК щодо іншої таблиці, яка ускладнювала це:

Я використовував цей запит, щоб перевірити, чи справді ідентичність відсутня, і щоб переглянути залежності від таблиці.

1.) Знайдіть статистику на таблиці:

exec sp_help 'dbo.table_name_old';

2.) Створіть повторювану ідентичну нову таблицю, за винятком додавання поля ідентичності в поле PK, де воно було раніше.

3.) Вимкніть особи для переміщення даних.

SET IDENTITY_INSERT dbo.table_name ON 

4.) Передача даних.

INSERT INTO dbo.table_name_new
(
field1, field2, etc...
)
SELECT 
field1, field2, etc...
FROM 
dbo.table_name_old;

5.) Перевірте, чи є дані.

SELECT * FROM dbo.table_name_new

6.) Повторно ввімкніть особу.

SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF

7.) Це найкращий сценарій, який я знайшов, щоб отримати всі відносини FK, щоб перевірити, яку таблицю (-и) оригінальна таблиця посилається на залежність, і я натрапив на багатьох, тож він є хранителем!

SELECT f.name AS ForeignKey,
   OBJECT_NAME(f.parent_object_id) AS TableName,
   COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
   OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
   COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
   ON f.OBJECT_ID = fc.constraint_object_id
   ORDER BY ReferenceTableName;

8.) Перед цим наступним кроком переконайтеся, що у вас є всі сценарії PK та FK для всіх залучених таблиць.

9.) Можна клацнути правою кнопкою миші на кожній клавіші та скриптувати це за допомогою SQL Server 2008

10.) Викиньте FK (s) з таблиці (ів) залежності, використовуючи цей синтаксис:

ALTER TABLE [dbo].[table_name] DROP CONSTRAINT [Name_of_FK]

11.) Опустіть оригінальну таблицю:

DROP TABLE dbo.table_name_old;

13.) Наступні кроки покладаються на сценарії, створені у SQL Server 2008 на кроці 9.

--Додайте ПК до нової таблиці.

--Додайте FK до нової таблиці.

--Додайте спинку FK до таблиці залежностей.

14.) Перевірте, чи все правильно і повно. Я використовував графічний інтерфейс для перегляду таблиць.

15.) Перейменуйте нову таблицю в назву оригінальної таблиці.

exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]';

Нарешті, все спрацювало!


4

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

якщо ви використовуєте SSMS і встановите властивість ідентичності в режимі ON у дизайнері, ось що робить SQL Server за кадром. Отже, якщо у вас є таблиця з іменем [user], це відбувається, якщо ви робите UserID та ідентифікатор

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

Сказавши, що є спосіб зламати системну таблицю, щоб досягти її, встановивши побітове значення, але це не підтримується, і я б не робив цього


4

Як я зрозумів, у звичайних випадках ми створюємо таблицю з Первинним ключем, який має властивість Identity,
тому перейменувати або видалити стовпець, пов'язаний з обмеженням первинного ключа , неможливо, оскільки правила обмеження перевіряють структуру стовпців. Щоб досягти цього, ми повинні обробити деякі кроки наступним чином: Припустимо, що TableName = 'Співробітник' та ColumnName = 'EmployeeId' 1. Додайте новий стовпець 'EmployeeId_new' у таблицю «Співробітник» ПІДТРИМЛЕННЯ СТОЛОНА СЛУЖБА ДОДАЙТЕ СпівробітникId_new ІДЕНТИФІКАТОР ( 1,1)




  1. Тепер видаліть стовпець "EmployeeII" з таблиці "Співробітник"
    ПІДПРИЄМЛЕННЯ ТАБЛИЦІ СТРАХУВАННЯ СЛОВА СЛОВА

  2. Це призведе до помилки, оскільки правила обмеження первинного ключа застосовуються та перевіряють структуру стовпців.
    * ### ' Msg 5074, рівень 16, стан 1, рядок 1 Об'єкт [PK_dbo.E Employee] залежить від colmn [EmployeeII].' ###

  3. Таким чином, ми повинні видалити обмеження первинного ключа спочатку з таблиці "Співробітник", потім ми можемо видалити стовпець
    НАЗАД ТАБЛИЦІ ДЛЯ ПРАЦІ СЛУЖБА [PK_dbo.E Employee]

  4. Тепер ми можемо видалити стовпчик "EmployeeIId" з таблиці "Співробітник", як це було зроблено на попередньому кроці, де ми отримали помилку
    ПІДТРИМЛЕННЯ ТАБЛИЦІ СТРАНИЙ СЛОВА СЛОВА EmployeeId

  5. Тепер стовпчик "EmployeeII" видалено з таблиці. Отже, ми перейменоваємо новий доданий новий стовпець "EmployeeId_new" на "EmployeeII"
    sp_rename "Employee.EposleeeId", "EmployeeId_new", "COLUMN"

  6. Щоб змінити перестановку таблиці в такій формі, як це було, ми повинні додати обмеження первинного ключа для стовпця "EmployeeIId"
    ALTER TABLE Employee add constraint [PK_dbo.E Employee] первинний ключ (EmployeeeId)

8. Тепер таблицю "Співробітник" на "EmployeeII" змінено на правила ідентичності разом з існуючим обмеженням первинного ключа


3

За задумом не існує простого способу ввімкнути або вимкнути функцію ідентичності для існуючого стовпця. Єдиний чистий спосіб зробити це - створити новий стовпець і зробити його стовпцем ідентичності або створити нову таблицю та перемістити ваші дані.

Якщо ми використовуємо SQL Server Management Studio для позбавлення від значення ідентичності у стовпці "id", створюється нова тимчасова таблиця, дані переміщуються у тимчасову таблицю, стару таблицю видаляють та нову таблицю перейменовують.

Використовуйте студію управління, щоб внести зміни, а потім клацніть правою кнопкою миші на дизайнері та виберіть "Створити сценарій змін".

Ви побачите, що це те, що робить SQL-сервер у фоновому режимі.


2

Немає жодної, на жаль; властивість IDENTITY належить до таблиці, а не до стовпця.

Простіший спосіб - це зробити в графічному інтерфейсі, але якщо це не варіант, ви можете пройти довгий шлях копіювання даних, скидання стовпця, повторного додавання їх ідентичності та повернення даних назад.

Дивіться тут, щоб дізнатися, як ми бачимо.


2

Клацніть правою кнопкою миші на назві таблиці в Провіднику об’єктів. Ви отримаєте кілька варіантів. Клацніть на «Дизайн». Для цієї таблиці буде відкрита нова вкладка. Тут ви можете додати обмеження ідентичності у "Властивості стовпця".


2

Щоб змінити властивості ідентичності стовпця:

  • У Провіднику сервера клацніть правою кнопкою миші таблицю із властивостями ідентичності, яку потрібно змінити, і натисніть Відкрити визначення таблиці. Таблиця відкриється в «Дизайнері таблиць».
  • Зніміть прапорець Дозволити нулі для стовпця, який потрібно змінити.
  • На вкладці Властивості стовпця розгорніть властивість Специфікація ідентичності.
  • Клацніть на клітинку сітки для дочірньої властивості Is Identity та виберіть Так у спадному списку.
  • Введіть значення в комірку Seedity Seed. Це значення буде присвоєно першому рядку таблиці. Значення 1 буде призначене за замовчуванням.

Це все, і це працювало на мене


2

Якщо ви випадково використовуєте Visual Studio 2017+

  1. У Провіднику сервера об’єктів клацніть правою кнопкою миші на вашій таблиці та виберіть "переглянути код"
  2. Додайте модифікатор "ІДЕНТИЧНОСТІ" у свій стовпець
  3. Оновлення

Це зробить все за вас.


Так! Дякую за пропозицію! У мене немає вікна SSMS у вікні Windows 7, що дозволяє мені вносити зміни в таблиці на моєму виробничому сервері, оскільки це 2017 рік, мій SSMS - 2014, а для SSMS 2017 потрібен Windows 10. Ви зробили мій день. Зайшов у VS 2017> Server Explorer> зробив нове підключення до виробництва SQL Server> клацнув правою кнопкою миші на таблиці> "Відкриття визначення таблиці"> Wala!
JustJohn

Насправді я виявив, що ви можете натиснути правою кнопкою миші на поле та вибрати пункт Властивості та зробити там особи, вибравши Так чи Ні
JustJohn

1

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

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

Зверніть увагу на дужки навколо назви стовпця після PRIMARY KEYпараметра.

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


1

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

Як я хочу додати ідентифікацію, тому вона завжди починається від 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/

Додайте первинний ключ до наявної таблиці


0

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

Крім того, ви можете створити новий рядок у якості стовпця особи, скинути старий стовпець, а потім перейменувати новий.

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

2
майте на увазі, що якщо ви зробите це через SSMS / Enterprise Manager - ви будете створювати нову таблицю, копіювати дані, скидати стару таблицю та перейменовувати нову. Це може бути досить дорого, якщо у вас великі столи ...
Скотт Айві,

0

В основному є чотири логічні кроки.

  1. Створіть новий стовпець особистих даних. Увімкніть вставку ідентичності для цього нового стовпця.

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

  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

генерує скрипт для всіх таблиць з первинним ключем = 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.