SQL Server добавляет автоинкрементный первичный ключ к существующей таблице


253

Как заголовок, у меня есть существующая таблица, которая уже заполнена 150000 записей. Я добавил столбец Id (который в настоящее время нулевой).

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

Ответы:


429

Нет - вы должны сделать это наоборот: добавьте это прямо с самого начала, поскольку INT IDENTITYэто будет заполнено значениями идентичности, когда вы сделаете это:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY

и тогда вы можете сделать его первичным ключом:

ALTER TABLE dbo.YourTable
   ADD CONSTRAINT PK_YourTable
   PRIMARY KEY(ID)

или если вы предпочитаете делать все за один шаг:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY
       CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

2
Это действительно хороший ответ, но как я могу изменить начальное целое число от 1 до 1000? Я хотел бы начать считать с 1000. Я подозреваю, что могу использовать, ALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1но я не хотел пробовать это без проверки с экспертом :) Реф. pic.dhe.ibm.com/infocenter/iseries/v7r1m0/...
user1477388

3
Я только использовал это, и это, кажется, работалоalter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
user1477388

1
@stom: если вы ничего не указали, будут использованы seed = 1 и increment = 1 - в любом случае это наиболее часто используемая настройка. Если вы создали такую ​​таблицу - она ​​будет работать нормально. Но я бы рекомендовал всегда явно указывать начальное значение и приращение в ваших сценариях SQL - особенно для больших сайтов. Это просто хорошая практика.
marc_s

1
@stom: ну, PRIMARY KEYподразумевается, что NOT NULLэто на месте - и опять же - это не является абсолютно необходимым. Но я предпочитаю быть откровенным, и поэтому у меня всегда NOT NULLесть, просто чтобы быть абсолютно ясным
marc_s

3
@ turbo88: когда вы определяете свой PRIMARY KEY, кластерный индекс создается автоматически для вас (если вы не укажете явно NONCLUSTERED)
marc_s

19

Вы не можете «включить» IDENTITY: это перестройка таблицы.

Если вас не волнует порядок нумерации, вы бы добавили столбец NOT NULL с IDENTITY за один раз. 150 тысяч строк не много.

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



Весь экземпляр должен быть запущен в однопользовательском режиме, поэтому, вероятно, в большинстве случаев он не жизнеспособен, но ALTER TABLE ... SWITCHможет сделать это без этого.
Мартин Смит

11

У меня была эта проблема, но я не мог использовать столбец идентификации (по разным причинам). Я остановился на этом:

DECLARE @id INT
SET @id = 0 
UPDATE table SET @id = id = @id + 1 

Заимствовано отсюда .


4

Если столбец уже существует в вашей таблице и он пуст, вы можете обновить столбец с помощью этой команды (заменить id, tablename и tablekey):

UPDATE x
SET x.<Id> = x.New_Id
FROM (
  SELECT <Id>, ROW_NUMBER() OVER (ORDER BY <tablekey>) AS New_Id
  FROM <tablename>
  ) x

Вы сэкономили мне время с этим! Хорошее дополнение к ответу @ gbn.
Кристен Уэйт

2

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


2

дизайнером вы можете установить идентичность (1,1), щелкните правой кнопкой мыши на tbl => desing => в левой части (правой кнопкой мыши) => properties => в столбцах идентификаторов выберите #column

свойства

колонна идей


1
У вас есть информация о том, что это хороший подход? ОП спрашивает, является ли это «правильным путем». Более полный ответ может помочь им узнать плюсы и минусы этого подхода.
jinglesthula

На самом деле я использую эту опцию в среде разработки, если вы не хотите передать это изменение в производство, вы должны проверить с помощью VIEW DEPENDENCY, если поле идентификации используется какой-либо процедурой Store o o триггере.
Густаво Эррера

2

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

USE [Db_YourDbName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Drop TABLE [dbo].[Tbl_TourTable]

CREATE TABLE [dbo].[Tbl_TourTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NULL,
    [Family] [nvarchar](150) NULL)  

GO

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] ON 

INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] off 

0

Вот идея, которую вы можете попробовать. Исходная таблица - без идентификатора столбца table1 создайте новую таблицу - вызовите table2 вместе с идентификатором столбца. скопировать данные из таблицы1 в таблицу2 - столбец идентификаторов автоматически заполняется автоматически увеличенными числами.

переименуйте исходную таблицу - table1 в table3 переименуйте новую таблицу - table2 в table1 (оригинальная таблица) Теперь у вас есть таблица1 с включенным столбцом идентификаторов и заполненная для существующих данных. Убедившись, что проблем нет, и работайте должным образом, уберите table3, когда он больше не нужен.


0

Создайте новую таблицу с другим именем и теми же столбцами, с первичным ключом и внешним ключом и свяжите это в своем коде оператора вставки. Например, для СОТРУДНИКОВ замените на СОТРУДНИКОВ.

CREATE TABLE EMPLOYEES(

    EmpId        INT NOT NULL IDENTITY(1,1), 
    F_Name       VARCHAR(20) ,
    L_Name       VARCHAR(20) ,
    DOB          DATE ,
    DOJ          DATE ,
    PRIMARY KEY (EmpId),
    DeptId int FOREIGN KEY REFERENCES DEPARTMENT(DeptId),
    DesgId int FOREIGN KEY REFERENCES DESIGNATION(DesgId),
    AddId int FOREIGN KEY REFERENCES ADDRESS(AddId)   
) 

Однако вы должны либо удалить существующую таблицу EMPLOYEE, либо внести некоторые изменения в соответствии с вашими требованиями.


0

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

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable' AND COLUMN_NAME = 'PKColumnName')
BEGIN


ALTER TABLE dbo.YourTable
   ADD PKColumnName INT IDENTITY(1,1)

CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

END

GO

0
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 

5
ты можешь это объяснить?
Мухаммед Дьяс Яскур

1
Хотя этот код может решить проблему OP, лучше всего включить объяснение того, как ваш код решает проблему OP. Таким образом, будущие посетители могут учиться на вашем посте и применять его к своему коду. SO - это не сервис кодирования, а ресурс для знаний. Кроме того, высококачественные, полные ответы, скорее всего, будут проголосованы. Эти функции, наряду с требованием, чтобы все сообщения были автономными, являются одними из сильных сторон SO как платформы, которая отличает ее от форумов. Вы можете редактировать, чтобы добавить дополнительную информацию и / или дополнить ваши пояснения исходной документацией.
YSF

-1

изменить таблицу / ** вставить имя таблицы ** / добавить идентификатор int IDENTITY (1,1)

удалить из / ** вставить имя таблицы ** / где идентификатор в

(

выберите a.id FROM / ** вставьте имя табуляции / в качестве ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ (ВЫБЕРИТЕ МИН (id) в качестве идентификатора ОТ / вставьте имя табуляции / GROUP BY / вставьте столбцы c1, c2 .... ** /

) as t1 
ON a.id = t1.id

ГДЕ t1.id НЕДЕЙСТВИТЕЛЕН

)

изменить таблицу / ** вставить имя таблицы ** / DROP COLUMN id


Каков твой вопрос? Как спросить
Энн Килзер

1
Отредактируйте свой ответ, используя markdown, чтобы правильно отформатировать пример кода.
Билл Келлер

-3

Попробуйте что-то вроде этого (сначала на тестовой таблице):

USE your_database_name
ИДТИ
WHILE (ВЫБЕРИТЕ COUNT (*) ИЗ your_table WHERE your_id_field IS NULL)> 0
НАЧАТЬ
    УСТАНАВЛИВАЙТЕ РАУНД
    ОБНОВЛЕНИЕ your_table SET your_id_field = MAX (your_id_field) +1
КОНЕЦ
ПЕЧАТЬ 'ВСЕ СДЕЛАНО'

Я не проверял это вообще, так что будьте осторожны!


1
-1 Не отвечает на вопрос (о добавлении IDENTITYстолбцов) и не будет работать в любом случае. UPDATE your_table SET your_id_field = MAX(your_id_field)+1ты не можешь просто забить MAXтуда. Где находится WHEREпункт, чтобы избежать повторного обновления одной и той же строки?
Мартин Смит,

-3

Это работает в MariaDB, поэтому я могу только надеяться, что это работает в SQL Server: удалите только что вставленный столбец ID, а затем используйте следующий синтаксис: -

ALTER TABLE table_name ADD id INT ПЕРВИЧНЫЙ КЛЮЧ AUTO_INCREMENT;

Нет необходимости в другом столе. Это просто вставляет столбец id, делает его основным индексом и заполняет его последовательными значениями. Если SQL Server этого не сделает, мои извинения за то, что я потратил ваше время.


-3

ALTER TABLE table_name ADD COLUMN ID INT NOT NULL ПЕРВИЧНЫЙ КЛЮЧ AUTO_INCREMENT; Это может быть полезно

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.