Primärschlüssel zur vorhandenen Tabelle hinzufügen


193

Ich habe eine vorhandene Tabelle namens Persion. In dieser Tabelle habe ich 5 Spalten:

  • persionId
  • Pname
  • PMid
  • Beschreibung
  • Pamt

Als ich diese Tabelle erstellt habe, habe ich PersionIdund Pnameals Primärschlüssel festgelegt .

Ich möchte jetzt eine weitere Spalte in den Primärschlüssel aufnehmen - PMID. Wie kann ich dazu eine ALTERErklärung schreiben ? (Ich habe bereits 1000 Datensätze in der Tabelle)


8
Bist du sicher? Dies bedeutet, dass Sie Duplikate personIdin Ihrer Tabelle haben dürfen. Dies bedeutet wiederum, dass Sie doppelte Datensätze erhalten, wenn Sie nur mit diesem Schlüssel von einer Tabelle vom Typ Transaktion (viele) zu dieser Tabelle beitreten, was zu einer Doppelzählung von Transaktionsdatensätzen führt.
Nick.McDermaid

6
in der Tat ist dies eine sehr schlechte Idee. Ihre PK sollte auf "persionId" sein, das war's
Patrick Honorez

1
Ich dachte, nur eine Spalte in einer Tabelle sollte als Primärschlüssel festgelegt werden?
CHarris

1
@ChristopheHarris, manchmal ist es sinnvoll, mehr als eine Spalte als Primärschlüssel zu haben. Eine Eins-zu-Viele- oder Viele-zu-Viele-Beziehungstabelle enthält wahrscheinlich zwei oder mehr Fremdschlüsselspalten, aus denen der Primärschlüssel besteht, da ein Datensatz nur dann eindeutig identifiziert werden kann, wenn Sie die Werte aller Primärschlüssel kennen Säulen. Im Fall des OP ist es jedoch unwahrscheinlich, dass dies wirklich das ist, was er wollte.
Kristen Hammack

2
@Kristen Hammack Selbst bei M2M-Beziehungen ist es wahrscheinlich besser, wenn die Zwischentabelle einen separaten Primärschlüssel hat und dann eine eindeutige Einschränkung für die beiden Fremdschlüssel zusammensetzt.
Kloddant

Antworten:


190

Löschen Sie die Einschränkung und erstellen Sie sie neu

alter table Persion drop CONSTRAINT <constraint_name>

alter table Persion add primary key (persionId,Pname,PMID)

bearbeiten:

Sie können den Einschränkungsnamen mithilfe der folgenden Abfrage ermitteln:

select OBJECT_NAME(OBJECT_ID) AS NameofConstraint
FROM sys.objects
where OBJECT_NAME(parent_object_id)='Persion'
and type_desc LIKE '%CONSTRAINT'

80

Ich denke so etwas sollte funktionieren

-- drop current primary key constraint
ALTER TABLE dbo.persion 
DROP CONSTRAINT PK_persionId;
GO

-- add new auto incremented field
ALTER TABLE dbo.persion 
ADD pmid BIGINT IDENTITY;
GO

-- create new primary key constraint
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId);
GO

1
Wahrscheinlich ist nicht geclustert eine gute Option bei zusammengesetzten PKs für die Leistung auf der Basis des Einfügedatums, wenn dies für Sie wichtig ist.
Shiv

36
-- create new primary key constraint
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId);

ist eine bessere Lösung, da Sie die Benennung des Primärschlüssels steuern können.


Es ist besser als nur zu benutzen

ALTER TABLE Persion ADD PRIMARY KEY(persionId,Pname,PMID)

Dies führt zu zufälligen Namen und kann Probleme beim Skripten oder Vergleichen von Datenbanken verursachen


3
+1 zum Hervorheben der Funktionalität zur Benennung Ihres Primärschlüssels. Wenn Sie Update-Skripte ausführen, die
PKs per

27

Wenn Sie eine Primärschlüsseleinschränkung hinzufügen

ALTER TABLE <TABLE NAME> ADD CONSTRAINT <CONSTRAINT NAME> PRIMARY KEY <COLUMNNAME>  

beispielsweise:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO)

13

In Ihrer Tabelle befindet sich bereits ein Primärschlüssel. Sie können nicht einfach einen Primärschlüssel hinzufügen, da dies sonst zu Fehlern führen kann. Weil es einen Primärschlüssel für die SQL-Tabelle gibt.

Zuerst müssen Sie Ihren alten Primärschlüssel ablegen.

MySQL:

ALTER TABLE Persion
DROP PRIMARY KEY;

SQL Server / Oracle / MS Access:

ALTER TABLE Persion
DROP CONSTRAINT 'constraint name';

Sie müssen den Einschränkungsnamen in Ihrer Tabelle finden. Wenn Sie beim Erstellen einer Tabelle einen Einschränkungsnamen angegeben haben, können Sie den Einschränkungsnamen (z. B. PK_Persion) problemlos verwenden.

Zweitens Primärschlüssel hinzufügen.

MySQL / SQL Server / Oracle / MS-Zugriff:

ALTER TABLE Persion ADD PRIMARY KEY (PersionId,Pname,PMID);

oder der bessere unten

ALTER TABLE Persion ADD CONSTRAINT PK_Persion PRIMARY KEY (PersionId,Pname,PMID);

Dies kann den Einschränkungsnamen vom Entwickler festlegen. Es ist einfacher, den Tisch zu pflegen.

Ich bin etwas verwirrt, als ich alle Antworten angeschaut habe. Also recherchiere ich in einem Dokument, um jedes Detail zu finden. Hoffe, diese Antwort kann anderen SQL-Anfängern helfen.

Referenz: https://www.w3schools.com/sql/sql_primarykey.asp


4

Die PRIMARY KEY-Einschränkung identifiziert jeden Datensatz in einer Datenbanktabelle eindeutig. Primärschlüssel müssen EINZIGARTIGE Werte enthalten und die Spalte darf keine NULL-Werte enthalten.

  -- DROP current primary key 
  ALTER TABLE tblPersons DROP CONSTRAINT <constraint_name>
  Example:
  ALTER TABLE tblPersons 
  DROP CONSTRAINT P_Id;


  -- ALTER TABLE tblpersion
  ALTER TABLE tblpersion add primary key (P_Id,LastName)

4

Nekromantie.
Nur für den Fall, dass jemand ein so gutes Schema hat wie ich ...
So geht's richtig:

In diesem Beispiel lautet der Tabellenname dbo.T_SYS_Language_Forms und der Spaltenname LANG_UID

-- First, chech if the table exists...
IF 0 < (
    SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = 'BASE TABLE'
    AND TABLE_SCHEMA = 'dbo'
    AND TABLE_NAME = 'T_SYS_Language_Forms'
)
BEGIN
    -- Check for NULL values in the primary-key column
    IF 0 = (SELECT COUNT(*) FROM T_SYS_Language_Forms WHERE LANG_UID IS NULL)
    BEGIN
        ALTER TABLE T_SYS_Language_Forms ALTER COLUMN LANG_UID uniqueidentifier NOT NULL 

        -- No, don't drop, FK references might already exist...
        -- Drop PK if exists (it is very possible it does not have the name you think it has...)
        -- ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT pk_constraint_name 
        --DECLARE @pkDropCommand nvarchar(1000) 
        --SET @pkDropCommand = N'ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT ' + QUOTENAME((SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
        --WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' 
        --AND TABLE_SCHEMA = 'dbo' 
        --AND TABLE_NAME = 'T_SYS_Language_Forms' 
        ----AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms' 
        --))
        ---- PRINT @pkDropCommand 
        --EXECUTE(@pkDropCommand) 
        -- Instead do
        -- EXEC sp_rename 'dbo.T_SYS_Language_Forms.PK_T_SYS_Language_Forms1234565', 'PK_T_SYS_Language_Forms';

        -- Check if they keys are unique (it is very possible they might not be)        
        IF 1 >= (SELECT TOP 1 COUNT(*) AS cnt FROM T_SYS_Language_Forms GROUP BY LANG_UID ORDER BY cnt DESC)
        BEGIN

            -- If no Primary key for this table
            IF 0 =  
            (
                SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
                WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' 
                AND TABLE_SCHEMA = 'dbo' 
                AND TABLE_NAME = 'T_SYS_Language_Forms' 
                -- AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms' 
            )
                ALTER TABLE T_SYS_Language_Forms ADD CONSTRAINT PK_T_SYS_Language_Forms PRIMARY KEY CLUSTERED (LANG_UID ASC)
            ;

        END -- End uniqueness check
        ELSE
            PRINT 'FSCK, this column has duplicate keys, and can thus not be changed to primary key...' 
    END -- End NULL check
    ELSE
        PRINT 'FSCK, need to figure out how to update NULL value(s)...' 
END 

Sehr guter Punkt zu "Nicht fallen lassen, FK-Referenzen sind möglicherweise bereits vorhanden". Die anderen Antworten haben aus diesem Grund bei mir nicht funktioniert.
Sgryzko

2

Bitte versuchen Sie dies-

ALTER TABLE TABLE_NAME DROP INDEX `PRIMARY`, ADD PRIMARY KEY (COLUMN1, COLUMN2,..);

1

Versuchen Sie es mit diesem Code:

ALTER TABLE `table name` 
    CHANGE COLUMN `column name` `column name` datatype NOT NULL, 
    ADD PRIMARY KEY (`column name`) ;

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.