sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo agregar una clave principal a una tabla existente en SQL Server (ejemplos de T-SQL)

Este artículo muestra cómo agregar una clave principal a una tabla existente en SQL Server mediante Transact-SQL.

Una clave principal es una columna que se ha configurado como identificador único para una tabla determinada.

Normalmente crearía una restricción de clave principal cuando crea la tabla, pero también puede agregar una clave principal a una tabla existente.

Tenga en cuenta que una tabla solo puede tener una clave principal. Por lo tanto, no puede agregar una clave principal si la tabla ya tiene una.

Además, las claves principales solo se pueden agregar a las columnas que se definen como NOT NULL .

Ejemplo 1:agregar una restricción de clave principal

En este ejemplo, creo una tabla, pero olvidé agregar una restricción de clave principal. Entonces vuelvo y modifico la tabla para tener una clave principal.

Cree la tabla (pero olvídese de crear una clave principal ):

USE Test;

CREATE TABLE Colors
(
    ColorId int IDENTITY (1,1) NOT NULL,
    ColorName varchar(50)
);

Resultado:

Commands completed successfully.
Total execution time: 00:00:00.058

Vaya, ¡olvidé crear la clave principal!

¡No hay problema! Podemos agregar uno ahora:

ALTER TABLE Colors
ADD CONSTRAINT PK_Colors_ColorId PRIMARY KEY CLUSTERED (ColorId);

Resultado:

Commands completed successfully.
Total execution time: 00:00:00.031

Esto ahora ha agregado una PRIMARY KEY restricción para el ColorId columna.

Ejemplo 2:verificar la restricción de clave principal

Ejecutemos el siguiente código para devolver una lista de restricciones de clave principal en la base de datos:

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Resultado:

+------------------------------+--------+-------------------+-------------------+
| name                         | type   | unique_index_id   | is_system_named   |
|------------------------------+--------+-------------------+-------------------|
| PK__MyTest__606C418F16F9CCCF | PK     | 1                 | 1                 |
| PK__Client__96ADCE1ACB91C2A9 | PK     | 1                 | 1                 |
| PK_Colors_ColorId            | PK     | 1                 | 0                 |
+------------------------------+--------+-------------------+-------------------+

Sus resultados serán diferentes, dependiendo de las claves principales en su base de datos.

También tenga en cuenta que esta vista del sistema devuelve más columnas de las que he especificado aquí, pero puede usar el * comodín para devolver todas las columnas si lo desea.

Ejemplo 3:agregar una clave principal a una columna que permite valores NULL

Una clave principal solo se puede agregar a las columnas definidas como NOT NULL . Si intenta agregar una clave principal a una columna que admite valores NULL, obtendrá un error.

Para demostrar esto, creemos otra tabla, pero esta vez, también nos olvidaremos de especificar la columna como NOT NULL :

USE Test;

CREATE TABLE Colors2
(
    ColorId int,
    ColorName varchar(50)
);

Podemos ejecutar la siguiente consulta para verificar si la columna permite valores nulos o no:

SELECT 
  t.name AS 'Table',
  c.name AS 'Column', 
  c.is_nullable,
  c.is_identity
FROM sys.columns c
INNER JOIN sys.tables T
ON c.object_id = t.object_id
WHERE c.name = 'ColorId';

Resultado:

+---------+----------+---------------+---------------+
| Table   | Column   | is_nullable   | is_identity   |
|---------+----------+---------------+---------------|
| Colors  | ColorId  | 0             | 1             |
| Colors2 | ColorId  | 1             | 0             |
+---------+----------+---------------+---------------+

Podemos ver que el que creamos anteriormente (en el Colors table) admite valores NULL y es una columna de identidad. El segundo (en el Colors2 table) es anulable y no es una columna de identidad.

Ahora intentemos agregar una restricción de clave principal a la columna anulable:

ALTER TABLE Colors2
ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);

Resultado:

Msg 8111, Level 16, State 1, Line 1
Cannot define PRIMARY KEY constraint on nullable column in table 'Colors2'.
Msg 1750, Level 16, State 0, Line 1
Could not create constraint or index. See previous errors.

Entonces, en este caso, necesitaremos modificar la columna para que sea NOT NULL antes de intentar definirlo como la clave principal.

Podemos usar ALTER COLUMN dentro de una ALTER TABLE declaración para establecer esta columna en NOT NULL :

ALTER TABLE Colors2
ALTER COLUMN ColorId int NOT NULL;

Revisemos la columna nuevamente:

SELECT 
  t.name AS 'Table',
  c.name AS 'Column', 
  c.is_nullable,
  c.is_identity
FROM sys.columns c
INNER JOIN sys.tables T
ON c.object_id = t.object_id
WHERE c.name = 'ColorId';

Resultado:

+---------+----------+---------------+---------------+
| Table   | Column   | is_nullable   | is_identity   |
|---------+----------+---------------+---------------|
| Colors  | ColorId  | 0             | 1             |
| Colors2 | ColorId  | 0             | 0             |
+---------+----------+---------------+---------------+

Entonces podemos ver que Colors2 ahora está establecido en 0 , lo que significa que no admite valores NULL (no puede contener valores NULL).

También tenga en cuenta que la columna no una columna de identidad. Discutiré esto más tarde.

De todos modos, ahora que la columna está definida como NOT NULL podemos continuar y agregar la clave principal:

ALTER TABLE Colors2
ADD CONSTRAINT PK_Colors2_ColorId PRIMARY KEY CLUSTERED (ColorId);

Resultado:

Commands completed successfully.
Total execution time: 00:00:00.048

Para verificar, revisemos nuevamente todas las restricciones de clave principal para esta tabla:

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Resultado:

+------------------------------+--------+-------------------+-------------------+
| name                         | type   | unique_index_id   | is_system_named   |
|------------------------------+--------+-------------------+-------------------|
| PK__MyTest__606C418F16F9CCCF | PK     | 1                 | 1                 |
| PK__Client__96ADCE1ACB91C2A9 | PK     | 1                 | 1                 |
| PK_Colors_ColorId            | PK     | 1                 | 0                 |
| PK_Colors2_ColorId           | PK     | 1                 | 0                 |
+------------------------------+--------+-------------------+-------------------+

Nuestra nueva clave principal que llamamos PK_Colors2_ColorId ha sido añadido a la lista.

Ejemplo 4:modificación de una columna para que sea una columna de identidad

Las claves primarias a menudo se aplican a las columnas de identidad. Las columnas de identidad se definen como tales con IDENTITY palabra clave, seguida de un valor inicial y de incremento opcional entre paréntesis.

Cuando se agrega una nueva fila a la tabla, SQL Server proporciona un valor incremental único para la columna de identidad.

Si planea usar una columna de identidad, debe haberlo hecho ya. No puede modificar una columna existente para que sea una columna de identidad.

Cuando ejecuté la consulta anteriormente, pudimos ver que Colors2.ColorId la columna es no una columna de identidad (lo sabemos porque is_identity se establece en 0 ). Esto significa que creé el PK_Colors2_ColorId clave principal en una columna sin identidad.

Esto es lo que sucede si tratamos de modificar la tabla para que sea una columna de identidad:

ALTER TABLE Colors2
ALTER COLUMN 
  ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY;

Resultado:

Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'IDENTITY'.

Como se mencionó, para superar esto, debemos soltar la columna y comenzar de nuevo.

Si la columna ya contiene datos, deberá realizar un trabajo adicional. Eso está fuera del alcance de este artículo, pero aquí hay un ejemplo de eliminar la columna anterior y volver a crearla como una columna de identidad:

USE Test; 

DROP TABLE Colors2;

CREATE TABLE Colors2
(
    ColorId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    ColorName varchar(50)
);

Resultado:

Commands completed successfully.
Total execution time: 00:00:00.049

Tenga en cuenta que esta vez no proporcioné un nombre para la restricción de clave principal. En este caso, el sistema le creará un nombre.

Compruebe rápidamente la columna:

SELECT 
  t.name AS 'Table',
  c.name AS 'Column', 
  c.is_nullable,
  c.is_identity
FROM sys.columns c
INNER JOIN sys.tables T
ON c.object_id = t.object_id
WHERE c.name = 'ColorId';

Resultado:

+---------+----------+---------------+---------------+
| Table   | Column   | is_nullable   | is_identity   |
|---------+----------+---------------+---------------|
| Colors  | ColorId  | 0             | 1             |
| Colors2 | ColorId  | 0             | 1             |
+---------+----------+---------------+---------------+

Sí, ahora es una columna de identidad.

Echemos otro vistazo a las claves principales de esta tabla:

SELECT
  name,
  type,
  unique_index_id,
  is_system_named
FROM sys.key_constraints
WHERE type = 'PK';

Resultado:

+-------------------------------+--------+-------------------+-------------------+
| name                          | type   | unique_index_id   | is_system_named   |
|-------------------------------+--------+-------------------+-------------------|
| PK__MyTest__606C418F16F9CCCF  | PK     | 1                 | 1                 |
| PK__Client__96ADCE1ACB91C2A9  | PK     | 1                 | 1                 |
| PK_Colors_ColorId             | PK     | 1                 | 0                 |
| PK__Colors2__8DA7674D8F57294D | PK     | 1                 | 1                 |
+-------------------------------+--------+-------------------+-------------------+

Así que ahora tenemos una clave principal con nombre del sistema llamada PK__Colors2__8DA7674D8F57294D .