SQL Server adiciona chave primária de incremento automático à tabela existente

253

Como título, tenho uma tabela existente que já está preenchida com 150000 registros. Eu adicionei uma coluna de identificação (que atualmente é nula).

Suponho que posso executar uma consulta para preencher esta coluna com números incrementais e, em seguida, definir como chave primária e ativar o incremento automático. Essa é a maneira correta de prosseguir? E se sim, como preencho os números iniciais?

fearofawhackplanet
fonte

Respostas:

429

Não - você precisa fazer o contrário: adicione-o desde o início, pois INT IDENTITY- ele será preenchido com valores de identidade quando você fizer isso:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY

e então você pode torná-la a chave primária:

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

ou se você preferir fazer tudo em uma única etapa:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY
       CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED
marc_s
fonte
2
Essa é uma resposta muito boa, mas como posso alterar o número inteiro inicial de 1 para 1000? Eu gostaria de começar a contar com 1000. Eu suspeito que posso usar, ALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1mas não queria experimentá-lo sem verificar com um especialista :) pic.dhe.ibm.com/infocenter/iseries/v7r1m0/…
user1477388 8/13
3
Eu apenas usei isso e parece ter funcionadoalter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
user1477388
1
@ stom: se você não especificar nada, serão utilizados seed = 1 e increment = 1 - que é a configuração mais frequentemente usada. Se você criou uma tabela como esta - funcionará bem. Mas eu recomendaria sempre especificar explicitamente a semente e o incremento em seus scripts SQL - especialmente para um site maior. É apenas uma boa prática.
marc_s
1
@ stom: bem, o PRIMARY KEYque implica que NOT NULLestá no lugar - então novamente - não é absolutamente necessário. Mas eu prefiro ser explícito e então eu sempre tenho o NOT NULLlá, apenas para ser absolutamente claro
marc_s
3
@ turbo88: quando você define o seu PRIMARY KEY, o índice agrupado é criado automaticamente para você (a menos que você especifique explicitamente NONCLUSTERED)
marc_s
19

Você não pode "ativar" a IDENTIDADE: é uma reconstrução da tabela.

Se você não se importa com a ordem dos números, adicione a coluna NOT NULL, com IDENTITY de uma só vez. 150 mil linhas não são muito.

Se você precisar preservar alguma ordem numérica, adicione os números de acordo. Em seguida, use o designer da tabela SSMS para definir a propriedade IDENTITY. Isso permite que você gere um script que fará com que a coluna solte / adicione / mantenha números / faça novas propagandas para você.

gbn
fonte
5
O OP está no SQL Server 2008 para que haja uma maneira
Martin Smith
A instância inteira precisa ser iniciada no modo de usuário único, portanto, provavelmente não é viável na maioria das circunstâncias, mas é ALTER TABLE ... SWITCHpossível fazer isso sem isso.
Martin Smith
11

Eu tive esse problema, mas não consegui usar uma coluna de identidade (por vários motivos). Eu decidi sobre isso:

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

Emprestado daqui .

Kevin
fonte
4

Se a coluna já existir na sua tabela e for nula, você poderá atualizar a coluna com este comando (substitua id, tablename e tablekey):

UPDATE x
SET x.<Id> = x.New_Id
FROM (
  SELECT <Id>, ROW_NUMBER() OVER (ORDER BY <tablekey>) AS New_Id
  FROM <tablename>
  ) x
Renzo Ciot
fonte
Você me economizou tempo com este! Bom adendo à resposta de @ gbn.
Kristen Waite
2

Quando adicionamos uma coluna de identidade a uma tabela existente, ela será preenchida automaticamente, sem a necessidade de preenchê-la manualmente.

user3279092
fonte
2

pelo designer, você pode definir a identidade (1,1) clique com o botão direito do mouse em tbl => desing => na parte esquerda (clique com o botão direito) => properties => nas colunas de identidade, selecione #column

Propriedades

coluna idendtity

gustavo herrera
fonte
1
Você tem informações sobre se essa é uma boa abordagem? O OP está perguntando se é a "maneira correta de prosseguir". Uma resposta mais completa pode ajudá-los a conhecer os prós / contras da abordagem.
Jinglesthula 31/07
Realmente estou usando esta opção no ambiente de desenvolvimento, se você passar essa alteração para produção, deverá verificar com VIEW DEPENDENCY se o campo de identidade estiver sendo usado por algum procedimento de Store ou trigger.
gustavo herrera
2

Se sua tabela tiver relacionamento com outras tabelas usando sua chave primária ou estrangeira, talvez seja impossível alterar sua tabela. então você precisa soltar e criar a tabela novamente.
Para resolver esses problemas, você precisa gerar scripts clicando com o botão direito do mouse no banco de dados e, no conjunto de opções avançadas, digite o tipo de dados para script para esquema e dados. depois disso, use esse script com a alteração de sua coluna para identificar e gerar novamente a tabela usando sua consulta.
sua consulta será como aqui:

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 
Hamid
fonte
0

Aqui está uma ideia que você pode tentar. Tabela original - sem coluna de identidade table1 cria uma nova tabela - chame table2 junto com a coluna de identidade. copie os dados da tabela1 para a tabela2 - a coluna de identidade é preenchida automaticamente com números incrementados automaticamente.

renomeie a tabela original - tabela1 para tabela3 renomeie a nova tabela - tabela2 para tabela1 (tabela original) Agora você tem a tabela1 com a coluna identidade incluída e preenchida para os dados existentes. Depois de verificar se não há problema e funcionando corretamente, descarte a tabela3 quando não for mais necessário.

JH326
fonte
0

Crie uma nova tabela com nome diferente e as mesmas colunas, associação de chave primária e chave estrangeira e vincule-a na sua instrução de código Inserir. Por exemplo: Para EMPREGADO, substitua por EMPREGADOS.

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)   
) 

No entanto, você deve excluir a tabela EMPLOYEE existente ou fazer alguns ajustes de acordo com sua necessidade.

kumarP
fonte
0

Esta resposta é uma pequena adição à resposta mais votada e funciona para o SQL Server. A pergunta solicitou uma chave primária de incremento automático, a resposta atual adiciona a chave primária, mas não é sinalizada como incremento automático. O script abaixo verifica as colunas, a existência e adiciona-o com o sinalizador de incremento automático ativado.

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
John K.
fonte
0
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 
sandesh jain
fonte
5
você pode explicar isso?
Muhammad Dyas Yaskur 28/01
1
Embora esse código possa resolver o problema do OP, é melhor incluir uma explicação sobre como o seu código soluciona o problema do OP. Dessa forma, futuros visitantes podem aprender com sua postagem e aplicá-la ao próprio código. O SO não é um serviço de codificação, mas um recurso para o conhecimento. Além disso, respostas completas de alta qualidade têm mais probabilidade de serem votadas. Esses recursos, juntamente com o requisito de que todas as postagens sejam independentes, são alguns dos pontos fortes do SO como plataforma, que o diferencia dos fóruns. Você pode editar para adicionar informações adicionais e / ou complementar suas explicações com a documentação de origem.
ysf 01/06
-1

alter table / ** cole o nome da tabalha ** / add id int IDENTITY (1,1)

exclua de / ** cole o nome da tabala ** / where id in

(

selecione a.id FROM / ** cole o nome da tabala / como uma junção externa esquerda (SELECT MIN (id) como id FROM / cole o nome da tabala / GROUP BY / cole as colunas c1, c2 .... ** /

) as t1 
ON a.id = t1.id

ONDE t1.id É NULL

)

alterar tabela / ** colar o nome da tabalha ** / DROP COLUMN id

Mohamed Sakilani
fonte
Qual a sua pergunta? Como perguntar
Ann Kilzer
1
Edite sua resposta, usando a marcação para formatar corretamente seu exemplo de código.
Bill Keller
-3

Tente algo assim (em uma tabela de teste primeiro):

USE your_database_name
IR
ENQUANTO (SELECIONE A CONTAGEM (*) DA SUA_Tabela ONDE SEU_ID_CAMPO É NULO)> 0
INÍCIO
    SET ROWCOUNT 1
    UPDATE your_table SET your_id_field = MAX (your_id_field) +1
FIM
IMPRIMIR 'TUDO CONCLUÍDO'

Eu não testei isso, então tenha cuidado!

PacDemon
fonte
1
-1 Não responde à pergunta (que inclui adicionar IDENTITYcolunas) e não funcionaria de qualquer maneira. UPDATE your_table SET your_id_field = MAX(your_id_field)+1você não pode simplesmente jogar MAXlá. Onde está uma WHEREcláusula para evitar apenas atualizar repetidamente a mesma linha?
Martin Smith
-3

Isso funciona no MariaDB, então só espero que funcione no SQL Server: solte a coluna de ID que você acabou de inserir e use a seguinte sintaxe: -

ALTER TABLE nome_tabela ADICIONAR ID INT PRIMARY KEY AUTO_INCREMENT;

Não há necessidade de outra mesa. Isso simplesmente insere uma coluna de identificação, torna o índice primário e o preenche com valores sequenciais. Se o SQL Server não fizer isso, peço desculpas por desperdiçar seu tempo.

Guerreiro de estrada
fonte
-3

ALTER TABLE nome_da_tabela ADICIONAR ID DE COLUNA INT NÃO NULL PRIMARY KEY AUTO_INCREMENT; Isso pode ser útil

Assassino
fonte