Adicionar chave primária à tabela existente

194

Eu tenho uma tabela existente chamada Persion. Nesta tabela, eu tenho 5 colunas:

  • persionId
  • Pname
  • PMid
  • Pdescription
  • Pamt

Quando criei esta tabela, defino PersionIde Pnamecomo a chave primária .

Agora, quero incluir mais uma coluna na chave primária - PMID. Como posso escrever uma ALTERdeclaração para fazer isso? (Eu já tenho 1000 registros na tabela)

Jay
fonte
8
Você tem certeza? isso significa que você pode duplicar personIdna sua tabela. Por sua vez, isso significa que, se você ingressar de uma tabela de tipos de transação (muitos) nessa tabela, somente nessa chave, obterá registros duplicados, levando à "contagem dupla" de registros de transações.
NickMcDermaid
6
de fato, essa é uma péssima idéia. Seu PK deve estar em "persionId", é isso #
Patrick Honorez 12/11/2015
1
Eu pensei que apenas uma coluna em uma tabela deve ser definida como a chave primária?
CHarris 21/07
1
@ChristopheHarris, às vezes faz sentido ter mais de uma coluna como chave primária. Uma tabela de relacionamento um para muitos ou muitos para muitos provavelmente terá 2 ou mais colunas de chave estrangeira que compõem a chave primária, pois só é possível identificar exclusivamente um registro se você souber os valores de toda a chave primária colunas. No entanto, no caso do OP, é improvável que isso seja realmente o que ele estava querendo.
22816 Kristen Hammack
2
@Kristen Hammack Mesmo no caso de relacionamentos M2M, é provavelmente melhor que a tabela intermediária tenha uma chave primária separada e, em seguida, coloque uma restrição exclusiva nas duas chaves estrangeiras.
kloddant

Respostas:

191

eliminar restrições e recriá-las

alter table Persion drop CONSTRAINT <constraint_name>

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

editar:

você pode encontrar o nome da restrição usando a consulta abaixo:

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

Eu acho que algo assim deve funcionar

-- 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
TI
fonte
1
Provavelmente não agrupado em cluster é uma boa opção no caso de PKs compostas para desempenho na data da inserção, se isso for importante para você.
Shiv
36
-- create new primary key constraint
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId);

é uma solução melhor porque você tem controle sobre a nomeação da primary_key.


É melhor do que apenas usar

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

que gera nomes aleatórios e pode causar problemas ao criar scripts ou comparar bancos de dados

user3675542
fonte
3
+1 para destacar a funcionalidade para nomear sua chave primária. Quando você estiver executando a atualização scripts que PKs drop-recriar, é preferível bater PKs chamados de ter que interrogar o esquema de informações para descobrir o nome
e_i_pi
27

Se você adicionar uma restrição de chave primária

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

por exemplo:

ALTER TABLE DEPT ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO)
K GANGA
fonte
13

Já existe uma chave primária na sua tabela. Você não pode simplesmente adicionar chave primária, caso contrário, causará erro. Porque existe uma chave primária para a tabela sql.

Primeiro, você deve soltar sua chave primária antiga.

MySQL:

ALTER TABLE Persion
DROP PRIMARY KEY;

Acesso ao SQL Server / Oracle / MS:

ALTER TABLE Persion
DROP CONSTRAINT 'constraint name';

Você precisa encontrar o nome da restrição na sua tabela. Se você forneceu o nome da restrição ao criar a tabela, poderá usá-lo facilmente (ex: PK_Persion).

Segundo, adicione chave primária.

Acesso MySQL / SQL Server / Oracle / MS:

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

ou o melhor abaixo

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

Isso pode definir o nome da restrição pelo desenvolvedor. É mais fácil manter a mesa.

Fiquei um pouco confuso quando procurei todas as respostas. Então, pesquiso alguns documentos para encontrar todos os detalhes. Espero que esta resposta possa ajudar outro iniciante em SQL.

Referência: https://www.w3schools.com/sql/sql_primarykey.asp

劉鎮 瑲
fonte
4

A restrição PRIMARY KEY identifica exclusivamente cada registro em uma tabela do banco de dados. As chaves primárias devem conter valores UNIQUE e a coluna não pode conter valores 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)
Mike Clark
fonte
4

Necromante.
Caso alguém tenha um esquema tão bom para trabalhar como eu ...
Aqui está como fazê-lo corretamente:

Neste exemplo, o nome da tabela é dbo.T_SYS_Language_Forms e o nome da coluna é 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 
Stefan Steiger
fonte
Muito bom ponto sobre 'não deixe cair, referências FK já podem existir'. As outras respostas não funcionaram para mim por causa disso.
precisa saber é o seguinte
2

Por favor, tente isso-

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

Tente usar este código:

ALTER TABLE `table name` 
    CHANGE COLUMN `column name` `column name` datatype NOT NULL, 
    ADD PRIMARY KEY (`column name`) ;
Rekha Rajan
fonte
1
ALTER TABLE TABLE_NAME ADD PRIMARY KEY(`persionId`,`Pname`,`PMID`)
Harry Singh
fonte