2012-08-03 25 views
101

Mam istniejącą tabelę o nazwie Persion. W tej tabeli mam 5 kolumn:Dodaj klucz podstawowy do istniejącej tabeli

  • persionId
  • PNAME
  • PMID
  • Pdescription
  • Pamt

Kiedy stworzył ten stół, ustawić PersionId i PNAME jako główny klucz.

Chcę teraz dodać jeszcze jedną kolumnę do klucza podstawowego - PMID. Jak mogę napisać oświadczenie ALTER, aby to zrobić? (Mam już 1000 rekordy w tabeli)

+5

Czy jesteś pewien? oznacza to, że możesz mieć duplikat "personId" w swojej tabeli. To z kolei oznacza, że ​​przy dołączaniu z tabeli typu transakcji (wielu) do tej tabeli tylko ten klucz pozwala uzyskać zduplikowane rekordy, co prowadzi do "podwójnego liczenia" rekordów transakcji. –

+4

w rzeczywistości jest to bardzo zły pomysł. Twój PK powinien być na "persionId", to jest to –

+1

Myślałem, że tylko jedna kolumna w tabeli powinna być ustawiona jako klucz podstawowy? – CHarris

Odpowiedz

117

upuść ograniczenie i odtworzyć go

alter table Persion drop CONSTRAINT <constraint_name> 

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

edit:

można znaleźć nazwę wiązania za pomocą poniższego zapytania:

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

Nie zapomnij o nawiasach '(...)' w dodatku klucz podstawowy. – Avi

45

Myślę, że coś takiego powinno zadziałać:

-- 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 
+4

Dlaczego opcja NIEKLUZYWANA na PK? –

+0

Prawdopodobnie nieklastrowy jest dobrym rozwiązaniem w przypadku złożonych PK dla wydajności w dniu wstawienia daty, jeśli jest to dla Ciebie ważne. – Shiv

3

Ograniczenie PRIMARY KEY jednoznacznie identyfikuje każdy rekord w tabeli bazy danych. Klucze podstawowe muszą zawierać wartości UNIQUE, a kolumna nie może zawierać wartości NULL.

-- 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) 
19
-- create new primary key constraint 
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId); 

jest lepszym rozwiązaniem, ponieważ masz kontrolę nad nazewnictwa w primary_key.


Lepiej niż tylko za pomocą

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

który yeilds losowych nazw i może powodować problemy, gdy się lub skryptów porównanie baz

+0

Proszę zignorować [:] Uwaga dla siebie: 'ALTER TABLE Osoba DROP CONSTRAINT ' –

2

Necromancing.
tylko w przypadku, gdy ktoś ma dobry schemat pracy z jak ja ...
Oto jak to zrobić poprawnie:

W tym przykładzie nazwa tabela jest dbo.T_SYS_Language_Forms i nazwa kolumny jest 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 
+0

Bardzo dobra uwaga dotycząca "nie upuszczaj, referencje FK mogą już istnieć". Inne odpowiedzi z tego powodu nie zadziałały. – sgryzko

0

Spróbuj użyć tego kodu:

ALTER TABLE `table name` 
    CHANGE COLUMN `column name` `column name` datatype NOT NULL, 
    ADD PRIMARY KEY (`column name`) ; 
0
ALTER TABLE TABLE_NAME ADD PRIMARY KEY(`persionId`,`Pname`,`PMID`) 
11

Jeśli dodać klucz podstawowy

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

na przykład:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO) 
Powiązane problemy