I SQL Server kan du bruge sp_special_columns
systemlagret procedure til at identificere en unik identifikator for tabellen. Specifikt returnerer det det optimale sæt af kolonner, der unikt identificerer en række i tabellen. Det returnerer også automatisk opdaterede kolonner, når en værdi i rækken opdateres af en transaktion.
sp_special_columns
svarer til SQLSpecialColumns i ODBC.
Hvis der ikke er nogen kolonner, der entydigt kan identificere tabellen, er resultatsættet tomt.
Syntaks
Syntaksen ser sådan ud:
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 er påkrævet. De andre er valgfrie. Se Microsoft-dokumentationen for en detaljeret forklaring af hvert argument.
Eksempel 1 – Primær nøglekolonne
Her er et grundlæggende eksempel på en tabel med en primær nøglekolonne kaldet PersonId :
EXEC sp_special_columns Person;
Det kan også køres sådan her:
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 dette tilfælde returneres den primære nøglekolonne. Jeg ved, at dette er den primære nøglekolonne, fordi jeg oprettede tabellen med følgende kode:
CREATE TABLE Person ( PersonId int primary key, PersonName varchar(500) );
Så det ser ud til, at den lagrede procedure faktisk returnerede den optimale kolonne, der entydigt identificerer denne tabel.
Eksempel 2 – UNIK kolonne
Tabellen i dette eksempel har ikke en primær nøgle, men den har en UNIQUE
begrænsning.
Her er koden, der blev brugt til at oprette tabellen:
CREATE TABLE Event ( EventId int UNIQUE, EventName varchar(500) );
Så lad os nu udføre sp_special_columns
mod det bord:
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 dette tilfælde kolonnen med UNIQUE
begrænsning anses for at være den optimale unikke identifikator.
Dette betyder dog ikke nødvendigvis, at enhver kolonne begrænset af en UNIQUE
begrænsning vil automatisk kvalificere sig som en unik identifikator. Resultatet kan afhænge af, hvordan nulværdier behandles.
Eksempel 3 – @nullable-argumentet
Du kan bruge @nullable
argument for at angive, om de specielle kolonner kan acceptere en nulværdi.
Her kører jeg den samme kode igen, bortset fra at denne gang bruger jeg @nullable = 'O'
.
EXEC sp_special_columns Event, @nullable = 'O';
Resultat:
(0 rows affected)
Her bruger 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
angiver specielle kolonner, der ikke tillader null-værdier. U
angiver kolonner, der er delvist nulstillede. U
er standardværdien.
Her er, hvad der sker, hvis jeg opretter kolonnen 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)
Denne gang både O
og U
gav det samme resultat.
Hvis du har en tabel med flere UNIQUE
begrænsningskolonner, og nogle tillader nulværdier, mens andre ikke gør det, kan dette argument have indflydelse på, hvilken der anses for at være den optimale unikke identifikator. Se eksempel 7 nederst i denne artikel for et eksempel på, hvad jeg mener.
Eksempel 4 – IDENTITETSkolonne
Tabellen i dette eksempel har ikke en primær nøgle eller en UNIQUE
begrænsning, men den har en IDENTITY
kolonne.
Her er koden, der blev brugt til at oprette tabellen:
CREATE TABLE Product ( ProductId int IDENTITY, ProductName varchar(500) );
Så lad os nu udføre sp_special_columns
mod det bord:
EXEC sp_special_columns Product;
Resultat:
(0 rows affected)
Så det ser ud til, at IDENTITY
er ikke nok til entydigt at identificere denne tabel.
Eksempel 5 – Primær nøgle med flere kolonner
Her er en med en primærnøgle med flere kolonner. I dette tilfælde bruges to kolonner til den primære nøgle.
Her er koden, der blev brugt til at oprette tabellen:
CREATE TABLE PersonProduct ( PersonId int, ProductId int, CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId) );
Så lad os nu udføre sp_special_columns
mod det bord:
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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Eksempel 6 – Primær nøgle og UNIK begrænsning
Hvad hvis der er en primær nøgle og en UNIQUE
begrænsning i samme tabel?
Lad os finde ud af:
CREATE TABLE PersonEvent ( PersonEventId int UNIQUE, PersonId int, EventId int, CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId) );
Udfør sp_special_columns
mod det bord:
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ære nøgle vandt.
Hvad hvis vi skifter primærnøglen og UNIQUE
nøglekolonner omkring?
OK, lad os oprette endnu en hel tabel kun for det:
CREATE TABLE PersonEvent2 ( PersonEventId int PRIMARY KEY, PersonId int UNIQUE, EventId int UNIQUE );
Udfør sp_special_columns
mod det bord:
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ære nøgle vandt igen.
Eksempel 7 – Masser af UNIKKE begrænsninger
Hvad hvis hver kolonne har en UNIQUE
begrænsning?
CREATE TABLE Event2 ( EventId int UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Udfør sp_special_columns
mod det bord:
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 lad os se, hvad der sker, hvis vi indstiller en af disse kolonner til NOT NULL
, og brug derefter @nullable = 'O'
:
DROP TABLE Event2; CREATE TABLE Event2 ( EventId int NOT NULL UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Udfø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å kolonnen "ikke nullbar" er nu valgt som den optimale unikke identifikator.
Lad os nu udføre 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 er nu tilbage til den forrige kolonne.