SQL Server fügt der vorhandenen Tabelle den Primärschlüssel für die automatische Inkrementierung hinzu

253

Als Titel habe ich eine vorhandene Tabelle, die bereits mit 150000 Datensätzen gefüllt ist. Ich habe eine ID-Spalte hinzugefügt (die derzeit null ist).

Ich gehe davon aus, dass ich eine Abfrage ausführen kann, um diese Spalte mit inkrementellen Zahlen zu füllen, und dann als Primärschlüssel festlegen und die automatische Inkrementierung aktivieren kann. Ist dies der richtige Weg, um fortzufahren? Und wenn ja, wie fülle ich die Anfangsnummern?

Angst vor einem Hackplaneten
quelle

Antworten:

429

Nein - Sie müssen es umgekehrt machen: Fügen Sie es von Anfang an hinzu als INT IDENTITY- es wird mit Identitätswerten gefüllt, wenn Sie dies tun:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY

und dann können Sie es zum Primärschlüssel machen:

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

oder wenn Sie es vorziehen, alles in einem Schritt zu erledigen:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY
       CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED
marc_s
quelle
2
Dies ist eine wirklich gute Antwort, aber wie kann ich die Start-Ganzzahl von 1 auf 1000 ändern? Ich würde gerne bei 1000 anfangen zu zählen. Ich vermute, ich kann es verwenden, ALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1aber ich wollte es nicht versuchen, ohne es mit einem Experten zu besprechen :) Ref. pic.dhe.ibm.com/infocenter/iseries/v7r1m0/…
user1477388
3
Ich habe es gerade benutzt und es scheint funktioniert zu habenalter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
user1477388
1
@stom: Wenn Sie nichts angeben, werden seed = 1 und increment = 1 verwendet - dies ist ohnehin die am häufigsten verwendete Einstellung. Wenn Sie eine Tabelle wie diese erstellt haben, funktioniert sie einwandfrei. Ich würde jedoch empfehlen, den Startwert und das Inkrement in Ihren SQL-Skripten immer explizit anzugeben - insbesondere für eine größere Site. Es ist nur eine gute Übung.
marc_s
1
@stom: Nun, das PRIMARY KEYimpliziert, dass es vorhanden NOT NULList - also wieder - es ist nicht unbedingt notwendig. Aber ich ziehe es vor, explizit zu sein, und so habe ich immer das NOT NULLda, nur um absolut klar zu sein
marc_s
3
@ turbo88: Wenn Sie Ihre definieren PRIMARY KEY, wird der Clustered-Index automatisch für Sie erstellt (sofern Sie nicht ausdrücklich angeben NONCLUSTERED)
marc_s
19

Sie können die IDENTITÄT nicht "einschalten": Es handelt sich um eine Tabellenwiederherstellung.

Wenn Sie sich nicht für die Nummernreihenfolge interessieren, fügen Sie die Spalte NOT NULL mit IDENTITY auf einmal hinzu. 150k Zeilen sind nicht viel.

Wenn Sie eine bestimmte Nummernreihenfolge beibehalten müssen, fügen Sie die Nummern entsprechend hinzu. Verwenden Sie dann den SSMS-Tabellen-Designer, um die IDENTITY-Eigenschaft festzulegen. Auf diese Weise können Sie ein Skript generieren, das die Spalte Löschen / Hinzufügen / Behalten von Nummern / Neueinstellung für Sie ausführt.

gbn
quelle
5
Das OP ist auf SQL Server 2008, also gibt es einen Weg
Martin Smith
Die gesamte Instanz muss im Einzelbenutzermodus gestartet werden, sodass dies unter den meisten Umständen wahrscheinlich nicht möglich ALTER TABLE ... SWITCHist, aber ohne dies möglich ist.
Martin Smith
11

Ich hatte dieses Problem, konnte jedoch keine Identitätsspalte verwenden (aus verschiedenen Gründen). Ich habe mich dazu entschlossen:

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

Von hier ausgeliehen .

Kevin
quelle
4

Wenn die Spalte bereits in Ihrer Tabelle vorhanden ist und null ist, können Sie die Spalte mit diesem Befehl aktualisieren (ID, Tabellenname und Tabellenschlüssel ersetzen):

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
quelle
Du hast mir Zeit damit gespart! Guter Nachtrag zur Antwort von @ gbn.
Kristen Waite
2

Wenn wir eine Identitätsspalte in eine vorhandene Tabelle einfügen, wird diese automatisch ausgefüllt, ohne dass sie manuell ausgefüllt werden muss.

user3279092
quelle
2

Vom Designer können Sie die Identität festlegen (1,1). Klicken Sie mit der rechten Maustaste auf tbl => desing => teilweise links (Rechtsklick) => properties => Wählen Sie in den Identitätsspalten #column aus

Eigenschaften

Identitätsspalte

gustavo herrera
quelle
1
Haben Sie Informationen darüber, ob dies ein guter Ansatz ist? Das OP fragt, ob es die "richtige Vorgehensweise" ist. Eine vollständigere Antwort könnte ihnen helfen, die Vor- und Nachteile des Ansatzes zu kennen.
Jinglesthula
Ich verwende diese Option wirklich in einer Entwicklungsumgebung. Wenn Sie diese Änderung nicht an die Produktion übergeben möchten, sollten Sie mit VIEW DEPENDENCY überprüfen, ob das Identitätsfeld von einer Store-Prozedur oder einem Trigger verwendet wird.
Gustavo Herrera
2

Wenn Ihre Tabelle mit ihrem Primär- oder Foriegen-Schlüssel eine Beziehung zu anderen Tabellen hat, ist es möglicherweise unmöglich, Ihre Tabelle zu ändern. Sie müssen die Tabelle also löschen und erneut erstellen.
Um diese Probleme zu lösen, müssen Sie Skripte generieren, indem Sie mit der rechten Maustaste auf die Datenbank klicken und in der erweiterten Option den Datentyp auf Skript für Schema und Daten festlegen. Verwenden Sie anschließend dieses Skript, um Ihre Spalte zu ändern und die Tabelle mithilfe von run its query zu identifizieren und neu zu generieren.
Ihre Anfrage wird wie folgt sein:

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
quelle
0

Hier ist eine Idee, die Sie ausprobieren können. Originaltabelle - keine Identitätsspalte Tabelle1 Erstellen Sie eine neue Tabelle - rufen Sie Tabelle2 zusammen mit der Identitätsspalte auf. Kopieren Sie die Daten von Tabelle1 nach Tabelle2 - die Identitätsspalte wird automatisch mit automatisch inkrementierten Zahlen gefüllt.

Umbenennen der ursprünglichen Tabelle - Tabelle1 in Tabelle3 Umbenennen der neuen Tabelle - Tabelle2 in Tabelle1 (Originaltabelle) Jetzt haben Sie die Tabelle1 mit der Identitätsspalte eingeschlossen und für die vorhandenen Daten ausgefüllt. Nachdem Sie sichergestellt haben, dass kein Problem vorliegt und ordnungsgemäß funktioniert, lassen Sie die Tabelle3 fallen, wenn sie nicht mehr benötigt wird.

JH326
quelle
0

Erstellen Sie eine neue Tabelle mit unterschiedlichem Namen und denselben Spalten, Primärschlüssel- und Fremdschlüsselzuordnung und verknüpfen Sie diese in Ihrer Code-Anweisung Insert. Zum Beispiel: Für MITARBEITER durch MITARBEITER ersetzen.

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

Sie müssen jedoch entweder die vorhandene EMPLOYEE-Tabelle löschen oder einige Anpassungen gemäß Ihren Anforderungen vornehmen.

kumarP
quelle
0

Diese Antwort ist eine kleine Ergänzung zur am höchsten bewerteten Antwort und funktioniert für SQL Server. Bei der Frage wurde ein Primärschlüssel für die automatische Inkrementierung angefordert. Die aktuelle Antwort fügt zwar den Primärschlüssel hinzu, ist jedoch nicht als automatische Inkrementierung gekennzeichnet. Das folgende Skript überprüft die Spalten und die Existenz und fügt sie mit aktiviertem Autoincrement-Flag hinzu.

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.
quelle
0
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 
Sandesh Jain
quelle
5
kannst du es erklären?
Muhammad Dyas Yaskur
1
Während dieser Code das Problem des OP lösen kann, ist es am besten, eine Erklärung beizufügen, wie Ihr Code das Problem des OP behebt. Auf diese Weise können zukünftige Besucher aus Ihrem Beitrag lernen und ihn auf ihren eigenen Code anwenden. SO ist kein Codierungsdienst, sondern eine Ressource für Wissen. Es ist auch wahrscheinlicher, dass qualitativ hochwertige, vollständige Antworten positiv bewertet werden. Diese Funktionen sowie die Anforderung, dass alle Beiträge in sich geschlossen sind, sind einige der Stärken von SO als Plattform, die es von Foren unterscheidet. Sie können bearbeiten, um zusätzliche Informationen hinzuzufügen und / oder Ihre Erklärungen durch Quellendokumentation zu ergänzen.
ysf
-1

alter table / ** füge den Namen des Tabals ein ** / add id int IDENTITY (1,1)

lösche aus / ** füge den Namen des Tabals ein ** / wo id in

(

Wählen Sie a.id FROM / ** Einfügen des Tabalennamens / als LEFT OUTER JOIN (SELECT MIN (id) als ID FROM / Einfügen des Tabalennamens / GROUP BY / Einfügen der Spalten c1, c2 .... ** /

) as t1 
ON a.id = t1.id

WO t1.id NULL IST

)

alter table / ** füge den Namen des Tabals ein ** / DROP COLUMN id

Mohamed Sakilani
quelle
Was ist deine Frage? Wie man fragt
Ann Kilzer
1
Bearbeiten Sie Ihre Antwort mit Markdown, um Ihr Codebeispiel richtig zu formatieren.
Bill Keller
-3

Versuchen Sie so etwas (zuerst auf einem Testtisch):

BENUTZEN Sie Ihren_Datenbanknamen
GEHEN
WHILE (SELECT COUNT (*) FROM your_table WHERE your_id_field IS NULL)> 0
START
    ROWCOUNT EINSTELLEN 1
    UPDATE your_table SET your_id_field = MAX (your_id_field) +1
ENDE
DRUCKEN SIE 'ALL DONE'

Ich habe das überhaupt nicht getestet, also sei vorsichtig!

PacDemon
quelle
1
-1 Beantwortet die Frage nicht (es geht um das Hinzufügen von IDENTITYSpalten) und würde sowieso nicht funktionieren. UPDATE your_table SET your_id_field = MAX(your_id_field)+1Sie können nicht einfach da reinschmeißen MAX. Wo ist eine WHEREKlausel, um zu vermeiden, dass dieselbe Zeile wiederholt aktualisiert wird?
Martin Smith
-3

Dies funktioniert in MariaDB, daher kann ich nur hoffen, dass dies in SQL Server der Fall ist: Löschen Sie die soeben eingefügte ID-Spalte und verwenden Sie die folgende Syntax: -

ALTER TABLE Tabellenname ADD ID INT PRIMARY KEY AUTO_INCREMENT;

Keine Notwendigkeit für einen anderen Tisch. Dadurch wird einfach eine ID-Spalte eingefügt, zum Primärindex gemacht und mit sequentiellen Werten gefüllt. Wenn SQL Server dies nicht tut, entschuldige ich mich für die Verschwendung Ihrer Zeit.

Strassenkämpfer
quelle
-3

ALTER TABLE Tabellenname ADD COLUMN ID INT NICHT NULL PRIMARY KEY AUTO_INCREMENT; Dies könnte nützlich sein

Mörder
quelle