SQL Server ajoute la clé primaire d'incrémentation automatique à la table existante

253

Comme titre, j'ai une table existante qui est déjà remplie avec 150000 enregistrements. J'ai ajouté une colonne Id (qui est actuellement nulle).

Je suppose que je peux exécuter une requête pour remplir cette colonne avec des nombres incrémentiels, puis définir comme clé primaire et activer l'incrémentation automatique. Est-ce la bonne façon de procéder? Et si oui, comment remplir les premiers chiffres?

fearofawhackplanet
la source

Réponses:

429

Non - vous devez le faire dans l'autre sens: ajoutez-le dès le départ INT IDENTITY- il sera rempli de valeurs d'identité lorsque vous faites cela:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY

puis vous pouvez en faire la clé primaire:

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

ou si vous préférez tout faire en une seule étape:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY
       CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED
marc_s
la source
2
C'est une très bonne réponse, mais comment puis-je changer l'entier de départ de 1 à 1000? Je voudrais commencer à compter à 1000. Je soupçonne que je peux utiliser ALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1mais je ne voulais pas l'essayer sans vérifier avec un expert :) Réf. pic.dhe.ibm.com/infocenter/iseries/v7r1m0/…
user1477388
3
Je viens de l'utiliser et cela semble avoir fonctionnéalter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
user1477388
1
@stom: si vous ne spécifiez rien, seed = 1 et increment = 1 seront utilisés - ce qui est le paramètre le plus utilisé de toute façon. Si vous avez créé un tableau comme celui-ci, cela fonctionnera très bien. Mais je recommanderais de toujours spécifier explicitement le germe et l'incrément dans vos scripts SQL - en particulier pour un site plus grand. C'est juste une bonne pratique.
marc_s
1
@stom: eh bien, PRIMARY KEYcela implique qu'il NOT NULLest en place - encore une fois - ce n'est pas absolument nécessaire. Mais je préfère être explicite et donc j'ai toujours le NOT NULLlà, juste pour être absolument clair
marc_s
3
@ turbo88: lorsque vous définissez votre PRIMARY KEY, l'index cluster est créé automatiquement pour vous (sauf si vous le spécifiez explicitement NONCLUSTERED)
marc_s
19

Vous ne pouvez pas "allumer" l'IDENTITÉ: c'est une reconstruction de table.

Si vous ne vous souciez pas de l'ordre des numéros, vous ajouteriez la colonne, NON NULL, avec IDENTITÉ en une seule fois. 150 000 lignes, ce n'est pas beaucoup.

Si vous devez conserver l'ordre des numéros, ajoutez les numéros en conséquence. Utilisez ensuite le concepteur de table SSMS pour définir la propriété IDENTITY. Cela vous permet de générer un script qui effectuera la suppression / l'ajout / la conservation de numéros de colonne / le réensemencement pour vous.

gbn
la source
5
L'OP est sur SQL Server 2008 donc il y a un moyen
Martin Smith
L'instance entière doit être démarrée en mode mono-utilisateur, donc probablement pas viable dans la plupart des cas, mais elle ALTER TABLE ... SWITCHpeut le faire sans cela.
Martin Smith
11

J'ai eu ce problème, mais je n'ai pas pu utiliser une colonne d'identité (pour diverses raisons). Je me suis installé sur ceci:

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

Emprunté d' ici .

Kevin
la source
4

Si la colonne existe déjà dans votre table et qu'elle est nulle, vous pouvez mettre à jour la colonne avec cette commande (remplacez id, tablename et 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
la source
Tu m'as fait gagner du temps avec celui-ci! Bon addendum à la réponse de @ gbn.
Kristen Waite
2

Lorsque nous ajoutons une colonne d'identité dans une table existante, elle se remplit automatiquement, pas besoin de la remplir manuellement.

user3279092
la source
2

par le concepteur, vous pouvez définir l'identité (1,1), faites un clic droit sur tbl => desing => en partie à gauche (clic droit) => propriétés => dans les colonnes d'identité, sélectionnez #colonne

Propriétés

colonne idendtity

gustavo herrera
la source
1
Avez-vous des informations sur la bonne approche? Le PO demande si c'est la "bonne façon de procéder". Une réponse plus complète pourrait les aider à connaître les avantages / inconvénients de l'approche.
jinglesthula
Vraiment, j'utilise cette option dans un environnement de développement, si vous ne transmettez pas cette modification à la production, vous devriez vérifier avec VIEW DEPENDENCY si le champ d'identité est utilisé par une procédure Store ou un déclencheur.
gustavo herrera
2

Si votre table est en relation avec d'autres tables à l'aide de sa clé primaire ou foriegen, il peut être impossible de modifier votre table. vous devez donc supprimer et recréer la table.
Pour résoudre ces problèmes, vous devez générer des scripts en cliquant avec le bouton droit sur la base de données et dans le type d'options avancé, définissez le type de données à scripter sur le schéma et les données. après cela, l'utilisation de ce script avec la modification de votre colonne pour identifier et régénérer la table à l'aide de l'exécution de sa requête.
votre requête sera comme ici:

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
la source
0

Voici une idée que vous pouvez essayer. Table d'origine - pas de colonne d'identité table1 créez une nouvelle table - appelez table2 avec la colonne d'identité. copiez les données de table1 à table2 - la colonne d'identité est remplie automatiquement avec des nombres incrémentés automatiquement.

renommer la table d'origine - table1 en table3 renommer la nouvelle table - table2 en table1 (table d'origine) Vous avez maintenant la table1 avec la colonne d'identité incluse et remplie pour les données existantes. après vous être assuré qu'il n'y a pas de problème et avoir fonctionné correctement, supprimez la table3 lorsqu'elle n'est plus nécessaire.

JH326
la source
0

Créez une nouvelle table avec un nom différent et les mêmes colonnes, une association de clé primaire et de clé étrangère et liez-la dans votre instruction d'insertion de code. Par exemple: pour les EMPLOYÉS, remplacez-les par des EMPLOYÉS.

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

Cependant, vous devez soit supprimer la table des EMPLOYÉS existante, soit effectuer certains ajustements en fonction de vos besoins.

kumarP
la source
0

Cette réponse est un petit ajout à la réponse la plus votée et fonctionne pour SQL Server. La question demandait une clé primaire d'incrémentation automatique, la réponse actuelle ajoute la clé primaire, mais elle n'est pas signalée comme incrémentation automatique. Le script ci-dessous vérifie l'existence des colonnes et l'ajoute avec l'indicateur d'auto-incrémentation activé.

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.
la source
0
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 
sandesh jain
la source
5
pouvez-vous l'expliquer?
Muhammad Dyas Yaskur
1
Bien que ce code puisse résoudre le problème de l'OP, il est préférable d'inclure une explication sur la façon dont votre code résout le problème de l'OP. De cette façon, les futurs visiteurs peuvent apprendre de votre message et l'appliquer à leur propre code. SO n'est pas un service de codage, mais une ressource de connaissances. En outre, les réponses complètes de haute qualité sont plus susceptibles d'être votées positivement. Ces fonctionnalités, ainsi que l'exigence que tous les messages soient autonomes, sont quelques-unes des forces de SO en tant que plate-forme, ce qui le différencie des forums. Vous pouvez modifier pour ajouter des informations supplémentaires et / ou pour compléter vos explications avec la documentation source.
ysf
-1

alter table / ** collez le nom du tabal ** / add id int IDENTITY (1,1)

supprimer de / ** coller le nom du tabal ** / où id dans

(

sélectionnez a.id FROM / ** collez le nom du tabal / en tant que LEFT OUTER JOIN (SELECT MIN (id) comme id FROM / collez le nom du tabal / GROUP BY / collez les colonnes c1, c2 .... ** /

) as t1 
ON a.id = t1.id

O t t1.id EST NUL

)

modifier la table / ** coller le nom du tabal ** / DROP COLUMN id

Mohamed Sakilani
la source
Quelle est votre question? Comment demander
Ann Kilzer
1
Modifiez votre réponse à l'aide de démarque pour formater correctement votre exemple de code.
Bill Keller
-3

Essayez quelque chose comme ça (sur une table de test d'abord):

UTILISEZ votre_nom_de_base_de_données
ALLER
PENDANT (CHOISIR LE COMPTE (*) DE VOTRE_table OERE VOTRE_ID_Champ EST NUL)> 0
COMMENCER
    SET ROWCOUNT 1
    MISE À JOUR your_table SET your_id_field = MAX (your_id_field) +1
FIN
IMPRIMER «TOUT FAIT»

Je n'ai pas testé cela du tout, alors faites attention!

PacDemon
la source
1
-1 Ne répond pas à la question (qui consiste à ajouter des IDENTITYcolonnes) et ne fonctionnerait pas de toute façon. UPDATE your_table SET your_id_field = MAX(your_id_field)+1vous ne pouvez pas simplement rentrer MAXdedans. Où se trouve une WHEREclause pour éviter de simplement mettre à jour plusieurs fois la même ligne?
Martin Smith
-3

Cela fonctionne dans MariaDB, donc je ne peux qu'espérer que ce soit le cas dans SQL Server: supprimez la colonne ID que vous venez d'insérer, puis utilisez la syntaxe suivante: -

ALTER TABLE nom_table ADD id INT PRIMARY KEY AUTO_INCREMENT;

Pas besoin d'une autre table. Cela insère simplement une colonne id, en fait l'index principal et la remplit avec des valeurs séquentielles. Si SQL Server ne le fait pas, mes excuses pour avoir perdu votre temps.

Guerrier de la route
la source
-3

ALTER TABLE nom_table ADD COLUMN ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT; Cela pourrait être utile

Tueur
la source