En SQL Server, puede usar sp_special_columns
procedimiento almacenado del sistema para identificar un identificador único para la tabla. Específicamente, devuelve el conjunto óptimo de columnas que identifican de forma única una fila en la tabla. También devuelve columnas actualizadas automáticamente cuando una transacción actualiza cualquier valor en la fila.
sp_special_columns
es equivalente a SQLSpecialColumns en ODBC.
Si no hay columnas que puedan identificar de forma única la tabla, el conjunto de resultados está vacío.
Sintaxis
La sintaxis es así:
sp_special_columns [ @table_name = ] 'table_name' [ , [ @table_owner = ] 'table_owner' ] [ , [ @qualifier = ] 'qualifier' ] [ , [ @col_type = ] 'col_type' ] [ , [ @scope = ] 'scope' ] [ , [ @nullable = ] 'nullable' ] [ , [ @ODBCVer = ] 'ODBCVer' ] [ ; ]
El @table_name
se requiere argumento. Los demás son opcionales. Consulte la documentación de Microsoft para obtener una explicación detallada de cada argumento.
Ejemplo 1:columna de clave principal
Aquí hay un ejemplo básico en una tabla con una columna de clave principal llamada PersonId :
EXEC sp_special_columns Person;
También se puede ejecutar así:
EXEC sp_special_columns @table_name = 'Person';
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
En este caso, se devuelve la columna de clave principal. Sé que esta es la columna de clave principal, porque creé la tabla con el siguiente código:
CREATE TABLE Person ( PersonId int primary key, PersonName varchar(500) );
Entonces parece que el procedimiento almacenado devolvió la columna óptima que identifica de manera única esta tabla.
Ejemplo 2 – Columna ÚNICA
La tabla de este ejemplo no tiene una clave principal, pero tiene un UNIQUE
restricción.
Este es el código utilizado para crear la tabla:
CREATE TABLE Event ( EventId int UNIQUE, EventName varchar(500) );
Así que ahora ejecutemos sp_special_columns
contra esa mesa:
EXEC sp_special_columns Event;
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
En este caso, la columna con el UNIQUE
se considera que la restricción es el identificador único óptimo.
Sin embargo, esto no significa necesariamente que cualquier columna restringida por un UNIQUE
la restricción calificará automáticamente como un identificador único. El resultado puede depender de cómo se traten los valores nulos.
Ejemplo 3:el argumento @nullable
Puede usar @nullable
argumento para especificar si las columnas especiales pueden aceptar un valor nulo.
Aquí, vuelvo a ejecutar el mismo código, excepto que esta vez uso @nullable = 'O'
.
EXEC sp_special_columns Event, @nullable = 'O';
Resultado:
(0 rows affected)
Aquí está usando @nullable = 'U'
EXEC sp_special_columns Event, @nullable = 'U';
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
O
especifica columnas especiales que no permiten valores nulos. U
especifica columnas que son parcialmente anulables. U
es el valor predeterminado.
Esto es lo que sucede si creo la columna como NOT NULL
:
DROP TABLE Event; CREATE TABLE Event ( EventId int NOT NULL UNIQUE, EventName varchar(500) ); EXEC sp_special_columns Event, @nullable = 'U'; EXEC sp_special_columns Event, @nullable = 'O';
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ (1 row affected) +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ (1 row affected)
Esta vez ambos O
y U
produjo el mismo resultado.
Si tiene una tabla con múltiples UNIQUE
columnas de restricción, y algunas permiten valores nulos mientras que otras no, este argumento puede tener un impacto en cuál se considera que es el identificador único óptimo. Consulte el Ejemplo 7 al final de este artículo para ver un ejemplo de lo que quiero decir.
Ejemplo 4:columna IDENTIDAD
La tabla de este ejemplo no tiene una clave principal o un UNIQUE
restricción, pero tiene una IDENTITY
columna.
Este es el código utilizado para crear la tabla:
CREATE TABLE Product ( ProductId int IDENTITY, ProductName varchar(500) );
Así que ahora ejecutemos sp_special_columns
contra esa mesa:
EXEC sp_special_columns Product;
Resultado:
(0 rows affected)
Entonces parece que IDENTITY
no es suficiente para identificar de forma única esta tabla.
Ejemplo 5:clave principal de varias columnas
Aquí hay uno con una clave principal de varias columnas. En este caso, se utilizan dos columnas para la clave principal.
Este es el código utilizado para crear la tabla:
CREATE TABLE PersonProduct ( PersonId int, ProductId int, CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId) );
Así que ahora ejecutemos sp_special_columns
contra esa mesa:
EXEC sp_special_columns PersonProduct;
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 | | 1 | ProductId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Ejemplo 6:clave principal y restricción ÚNICA
¿Qué pasa si hay una clave principal y un UNIQUE
restricción en la misma tabla?
Averigüemos:
CREATE TABLE PersonEvent ( PersonEventId int UNIQUE, PersonId int, EventId int, CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId) );
Ejecute sp_special_columns
contra esa mesa:
EXEC sp_special_columns PersonEvent;
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 | | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Ganó la clave principal.
¿Qué pasa si cambiamos la clave principal y el UNIQUE
columnas clave alrededor?
Bien, creemos otra tabla completa solo para eso:
CREATE TABLE PersonEvent2 ( PersonEventId int PRIMARY KEY, PersonId int UNIQUE, EventId int UNIQUE );
Ejecute sp_special_columns
contra esa mesa:
EXEC sp_special_columns PersonEvent2;
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonEventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Así que la clave principal volvió a ganar.
Ejemplo 7:muchas restricciones ÚNICAS
¿Qué pasa si cada la columna tiene un UNIQUE
restricción?
CREATE TABLE Event2 ( EventId int UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Ejecute sp_special_columns
contra esa mesa:
EXEC sp_special_columns Event2;
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Pero veamos qué sucede si establecemos una de esas columnas en NOT NULL
, luego use @nullable = 'O'
:
DROP TABLE Event2; CREATE TABLE Event2 ( EventId int NOT NULL UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Ejecute sp_special_columns
con @nullable = 'O'
:
EXEC sp_special_columns Event2, @nullable = 'O';
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Por lo tanto, la columna "no anulable" ahora se elige como el identificador único óptimo.
Ahora ejecutemos sp_special_columns
con @nullable = 'U'
:
EXEC sp_special_columns Event2, @nullable = 'U';
Resultado:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Ahora vuelve a la columna anterior.