2012-08-03 18 views
101

Ho una tabella esistente denominata Persion. In questa tabella ho 5 colonne:Aggiungere la chiave primaria alla tabella esistente

  • persionId
  • pName
  • pmid
  • Pdescription
  • PamT

Quando ho creato questo tavolo, impostare PersionId e pname come chiave primaria.

Ora desidero includere un'altra colonna nella chiave primaria - PMID. Come posso scrivere una dichiarazione ALTER per fare questo? (Ho già 1000 record nella tabella)

+5

Sei sicuro? questo significa che puoi avere duplicato 'personId' nella tua tabella. Ciò a sua volta significa che se si accede da una tabella di tipo (molti) di transazione a questa tabella con questa chiave, si otterranno record duplicati, che porteranno al "doppio conteggio" dei record di transazione. –

+4

in effetti, questa è una pessima idea. Il tuo PK potrebbe essere su "persionId", questo è il –

+1

Ho pensato che solo una colonna in una tabella dovrebbe essere impostata come chiave primaria? – CHarris

risposta

117

vincolo goccia e ricrearla

alter table Persion drop CONSTRAINT <constraint_name> 

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

edit:

è possibile trovare il nome del vincolo utilizzando la query di seguito:

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

Non dimenticare le parentesi '(...)' in aggiunta la chiave primaria. – Avi

45

Penso che qualcosa del genere dovrebbe funzionare

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

Perché l'opzione NONCLUSTERED su un PK ??? –

+0

Probabilmente il non cluster è una buona opzione nel caso di PK compositi per le prestazioni in base alla data di inserimento, se ciò è importante per voi. – Shiv

3

Il vincolo PRIMARY KEY identifica in modo univoco ogni record in una tabella di database. Le chiavi primarie devono contenere valori UNIQUE e la colonna non può contenere valori 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); 

è una soluzione migliore perché avete il controllo sulla denominazione del primary_key.


E 'meglio che utilizzare

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

che yeilds nomi randomizzati e può causare problemi quando scripting fuori o si confrontano i database

+0

Ignora [:] Nota per sé: 'ALTER TABLE Person DROP CONSTRAINT ' –

2

Necromancing.
Nel caso in cui nessuno ha un buon schema per lavorare con me come ...
Ecco come farlo correttamente:

In questo esempio, il nome della tabella è dbo.T_SYS_Language_Forms, e il nome della colonna è 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

Ottimo punto su 'non lasciar cadere, i riferimenti FK potrebbero già esistere'. Le altre risposte non hanno funzionato per me a causa di questo. – sgryzko

0

Prova ad usare questo codice:

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

Se si aggiunge vincolo di chiave primaria

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

ad esempio:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO) 
Problemi correlati