Agregar clave primaria a la tabla existente

194

Tengo una tabla existente llamada Persion. En esta tabla tengo 5 columnas:

  • persionId
  • Pname
  • PMid
  • Pdescription
  • Pamt

Cuando creé esta tabla, configuré PersionIdy Pnamecomo clave principal .

Ahora quiero incluir una columna más en la clave primaria: PMID. ¿Cómo puedo escribir una ALTERdeclaración para hacer esto? (Ya tengo 1000 registros en la tabla)

arrendajo
fuente
8
¿Estás seguro? Esto significa que puede tener duplicados personIden su tabla. Esto a su vez significa que si se une desde una tabla de tipo transacción (muchos) a esta tabla solo en esta clave, obtendrá registros duplicados, lo que conducirá a un 'doble recuento' de registros de transacciones.
Nick.McDermaid
66
de hecho, esta es una idea MUY mala. Tu PK debería estar en "persionId", eso es todo
Patrick Honorez
1
¿Pensé que solo una columna en una tabla debería establecerse como la clave principal?
CHarris
1
@ChristopheHarris, a veces tiene sentido tener más de una columna como clave principal. Una tabla de relación de uno a muchos o de muchos a muchos probablemente tendrá 2 o más columnas de clave externa que componen la clave primaria, ya que solo es posible identificar de forma única un registro si conoce los valores de toda la clave primaria columnas Sin embargo, en el caso del OP, es poco probable que esto sea realmente lo que él quería.
Kristen Hammack
2
@Kristen Hammack Incluso en el caso de las relaciones M2M, probablemente sea mejor que la tabla intermedia tenga una clave primaria separada y luego establezca una restricción única en las dos claves externas.
kloddant

Respuestas:

191

soltar la restricción y recrearla

alter table Persion drop CONSTRAINT <constraint_name>

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

editar:

puede encontrar el nombre de la restricción utilizando la consulta a continuación:

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

Creo que algo como esto debería 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
fuente
1
Probablemente no agrupado es una buena opción en el caso de PK compuestos para el rendimiento en base a la fecha de inserción si eso es importante para usted.
Shiv
36
-- create new primary key constraint
ALTER TABLE dbo.persion 
ADD CONSTRAINT PK_persionId PRIMARY KEY NONCLUSTERED (pmid, persionId);

es una mejor solución porque tienes control sobre el nombre de la clave_primaria.


Es mejor que solo usar

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

que genera nombres aleatorios y puede causar problemas al crear scripts o comparar bases de datos

usuario3675542
fuente
3
+1 para resaltar la funcionalidad para nombrar su clave principal. Cuando ejecuta scripts de actualización que vuelven a crear PK, es preferible golpear PK con nombre que tener que interrogar el esquema de información para averiguar el nombre
e_i_pi
27

Si agrega restricción de clave primaria

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

por ejemplo:

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

Ya hay una clave principal en su tabla. No puede simplemente agregar la clave primaria, de lo contrario causará un error. Porque hay una clave primaria para la tabla sql.

Primero, debe soltar su antigua clave principal.

MySQL:

ALTER TABLE Persion
DROP PRIMARY KEY;

SQL Server / Oracle / MS Access:

ALTER TABLE Persion
DROP CONSTRAINT 'constraint name';

Tienes que encontrar el nombre de restricción en tu tabla. Si había dado un nombre de restricción cuando creó la tabla, puede usar fácilmente el nombre de restricción (por ejemplo: PK_Persion).

Segundo, Agregar clave primaria.

MySQL / SQL Server / Oracle / MS Access:

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

o el mejor de abajo

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

Esto puede establecer el nombre de restricción por desarrollador. Es más fácil mantener la mesa.

Me confundo un poco cuando busqué todas las respuestas. Así que investigo algún documento para encontrar cada detalle. Espero que esta respuesta pueda ayudar a otros principiantes de SQL.

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

劉鎮 瑲
fuente
4

La restricción PRIMARY KEY identifica de forma exclusiva cada registro en una tabla de base de datos. Las claves primarias deben contener valores ÚNICOS y la columna no puede contener 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
fuente
4

Nigromancia
En caso de que alguien tenga un esquema tan bueno para trabajar como yo ...
Aquí está cómo hacerlo correctamente:

En este ejemplo, el nombre de la tabla es dbo.T_SYS_Language_Forms, y el nombre de la columna es 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
fuente
Muy buen punto sobre 'no caer, las referencias FK ya pueden existir' Las otras respuestas no funcionaron para mí debido a esto.
sgryzko
2

Por favor intente esto

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

Intenta usar este código:

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