I SQL Server kan du använda sp_special_columns
systemlagrad procedur för att identifiera en unik identifierare för tabellen. Specifikt returnerar den den optimala uppsättningen kolumner som unikt identifierar en rad i tabellen. Den returnerar också automatiskt uppdaterade kolumner när något värde i raden uppdateras av en transaktion.
sp_special_columns
motsvarar SQLSpecialColumns i ODBC.
Om det inte finns några kolumner som unikt kan identifiera tabellen är resultatuppsättningen tom.
Syntax
Syntaxen ser ut så här:
sp_special_columns [ @table_name = ] 'table_name' [ , [ @table_owner = ] 'table_owner' ] [ , [ @qualifier = ] 'qualifier' ] [ , [ @col_type = ] 'col_type' ] [ , [ @scope = ] 'scope' ] [ , [ @nullable = ] 'nullable' ] [ , [ @ODBCVer = ] 'ODBCVer' ] [ ; ]
@table_name
argument krävs. De andra är valfria. Se Microsofts dokumentation för en detaljerad förklaring av varje argument.
Exempel 1 – Primär nyckelkolumn
Här är ett grundläggande exempel mot en tabell med en primärnyckelkolumn som heter PersonId :
EXEC sp_special_columns Person;
Det kan också köras så här:
EXEC sp_special_columns @table_name = 'Person';
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
I det här fallet returneras primärnyckelkolumnen. Jag vet att detta är den primära nyckelkolumnen, eftersom jag skapade tabellen med följande kod:
CREATE TABLE Person ( PersonId int primary key, PersonName varchar(500) );
Så det verkar som att den lagrade proceduren faktiskt returnerade den optimala kolumnen som unikt identifierar denna tabell.
Exempel 2 – UNIK kolumn
Tabellen i det här exemplet har ingen primärnyckel, men den har en UNIQUE
begränsning.
Här är koden som används för att skapa tabellen:
CREATE TABLE Event ( EventId int UNIQUE, EventName varchar(500) );
Så låt oss nu köra sp_special_columns
mot den tabellen:
EXEC sp_special_columns Event;
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
I det här fallet kolumnen med UNIQUE
begränsning anses vara den optimala unika identifieraren.
Detta betyder dock inte nödvändigtvis att någon kolumn begränsad av en UNIQUE
begränsning kommer automatiskt att kvalificeras som en unik identifierare. Resultatet kan bero på hur nollvärden behandlas.
Exempel 3 – @nullable-argumentet
Du kan använda @nullable
argument för att ange om specialkolumnerna kan acceptera ett nollvärde.
Här kör jag samma kod igen, förutom den här gången använder jag @nullable = 'O'
.
EXEC sp_special_columns Event, @nullable = 'O';
Resultat:
(0 rows affected)
Här använder den @nullable = 'U'
EXEC sp_special_columns Event, @nullable = 'U';
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
O
anger speciella kolumner som inte tillåter null-värden. U
anger kolumner som är delvis nullbara. U
är standardvärdet.
Här är vad som händer om jag skapar kolumnen som 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';
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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)
Den här gången både O
och U
gav samma resultat.
Om du har en tabell med flera UNIQUE
begränsningskolumner, och vissa tillåter null-värden medan andra inte gör det, kan detta argument ha en inverkan på vilken som anses vara den optimala unika identifieraren. Se exempel 7 längst ner i den här artikeln för ett exempel på vad jag menar.
Exempel 4 – IDENTITY Kolumn
Tabellen i det här exemplet har inte en primärnyckel eller en UNIQUE
begränsning, men den har en IDENTITY
kolumn.
Här är koden som används för att skapa tabellen:
CREATE TABLE Product ( ProductId int IDENTITY, ProductName varchar(500) );
Så låt oss nu köra sp_special_columns
mot den tabellen:
EXEC sp_special_columns Product;
Resultat:
(0 rows affected)
Så det verkar som att IDENTITY
är inte tillräckligt för att unikt identifiera denna tabell.
Exempel 5 – Primär nyckel med flera kolumner
Här är en med en primärnyckel med flera kolumner. I det här fallet används två kolumner för primärnyckeln.
Här är koden som används för att skapa tabellen:
CREATE TABLE PersonProduct ( PersonId int, ProductId int, CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId) );
Så låt oss nu köra sp_special_columns
mot den tabellen:
EXEC sp_special_columns PersonProduct;
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Exempel 6 – Primärnyckel och UNIK begränsning
Vad händer om det finns en primärnyckel och en UNIQUE
begränsning i samma tabell?
Låt oss ta reda på:
CREATE TABLE PersonEvent ( PersonEventId int UNIQUE, PersonId int, EventId int, CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId) );
Kör sp_special_columns
mot den tabellen:
EXEC sp_special_columns PersonEvent;
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Den primära nyckeln vann.
Vad händer om vi byter primärnyckel och UNIQUE
nyckelkolumner runt?
OK, låt oss skapa en annan hel tabell bara för det:
CREATE TABLE PersonEvent2 ( PersonEventId int PRIMARY KEY, PersonId int UNIQUE, EventId int UNIQUE );
Kör sp_special_columns
mot den tabellen:
EXEC sp_special_columns PersonEvent2;
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonEventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Så den primära nyckeln vann igen.
Exempel 7 – Många UNIKA begränsningar
Vad händer om varje kolumnen har en UNIQUE
begränsning?
CREATE TABLE Event2 ( EventId int UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Kör sp_special_columns
mot den tabellen:
EXEC sp_special_columns Event2;
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Men låt oss se vad som händer om vi ställer in en av dessa kolumner till NOT NULL
, använd sedan @nullable = 'O'
:
DROP TABLE Event2; CREATE TABLE Event2 ( EventId int NOT NULL UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Kör sp_special_columns
med @nullable = 'O'
:
EXEC sp_special_columns Event2, @nullable = 'O';
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Så kolumnen "inte nullbar" är nu vald som den optimala unika identifieraren.
Låt oss nu köra sp_special_columns
med @nullable = 'U'
:
EXEC sp_special_columns Event2, @nullable = 'U';
Resultat:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Det är nu tillbaka till föregående kolumn.