sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan finder du den optimale unikke identifikator i en tabel i SQL Server:sp_special_columns

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.


  1. Sådan beregnes glidende gennemsnit i PostgreSQL

  2. Dataingeniørinterviewspørgsmål med Python

  3. Har mysql det, der svarer til Oracles analytiske funktioner?

  4. Hvad er omkostningerne ved at bruge AUTOINCREMENT til SQLite på Android?