sql >> Database >  >> RDS >> Sqlserver

Hoe vindt u de optimale unieke identifier in een tabel in SQL Server:sp_special_columns

In SQL Server kunt u de sp_special_columns . gebruiken systeem opgeslagen procedure om een ​​unieke identificatie voor de tabel te identificeren. Het retourneert met name de optimale set kolommen die een rij in de tabel op unieke wijze identificeren. Het geeft ook kolommen terug die automatisch worden bijgewerkt wanneer een waarde in de rij wordt bijgewerkt door een transactie.

sp_special_columns is gelijk aan SQLSpecialColumns in ODBC.

Als er geen kolommen zijn die de tabel uniek kunnen identificeren, is de resultatenset leeg.

Syntaxis

De syntaxis gaat als volgt:

sp_special_columns [ @table_name = ] 'table_name'     
     [ , [ @table_owner = ] 'table_owner' ]   
     [ , [ @qualifier = ] 'qualifier' ]   
     [ , [ @col_type = ] 'col_type' ]   
     [ , [ @scope = ] 'scope' ]  
     [ , [ @nullable = ] 'nullable' ]   
     [ , [ @ODBCVer = ] 'ODBCVer' ]   
[ ; ]

De @table_name argumentatie vereist. De andere zijn optioneel. Zie de Microsoft-documentatie voor een gedetailleerde uitleg van elk argument.

Voorbeeld 1 – Kolom primaire sleutel

Hier is een basisvoorbeeld tegen een tabel met een primaire sleutelkolom genaamd PersonId :

EXEC sp_special_columns Person;

Het kan ook als volgt worden uitgevoerd:

EXEC sp_special_columns @table_name = 'Person';

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | PersonId      | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

In dit geval wordt de primaire sleutelkolom geretourneerd. Ik weet dat dit de primaire sleutelkolom is, omdat ik de tabel heb gemaakt met de volgende code:

CREATE TABLE Person (
  PersonId int primary key, 
  PersonName varchar(500)
  );

Het lijkt er dus op dat de opgeslagen procedure inderdaad de optimale kolom heeft geretourneerd die deze tabel op unieke wijze identificeert.

Voorbeeld 2 – UNIEKE kolom

De tabel in dit voorbeeld heeft geen primaire sleutel, maar wel een UNIQUE beperking.

Dit is de code die is gebruikt om de tabel te maken:

CREATE TABLE Event (
  EventId int UNIQUE, 
  EventName varchar(500)
  );

Dus laten we nu sp_special_columns uitvoeren tegen die tafel:

EXEC sp_special_columns Event;

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

In dit geval is de kolom met de UNIQUE beperking wordt beschouwd als de optimale unieke identifier.

Dit betekent echter niet noodzakelijkerwijs dat elke kolom beperkt door een UNIQUE beperking wordt automatisch gekwalificeerd als een unieke id. Het resultaat kan afhangen van hoe null-waarden worden behandeld.

Voorbeeld 3 – Het @nullable-argument

U kunt de @nullable . gebruiken argument om aan te geven of de speciale kolommen een null-waarde kunnen accepteren.

Hier voer ik dezelfde code opnieuw uit, maar deze keer gebruik ik @nullable = 'O' .

EXEC sp_special_columns 
  Event, 
  @nullable = 'O';

Resultaat:

(0 rows affected)

Hier gebruikt het @nullable = 'U'

EXEC sp_special_columns 
  Event, 
  @nullable = 'U';

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

O specificeert speciale kolommen die geen null-waarden toestaan. U specificeert kolommen die gedeeltelijk nullable zijn. U is de standaardwaarde.

Dit is wat er gebeurt als ik de kolom maak als 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';

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| 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)

Deze keer beide O en U produceerde hetzelfde resultaat.

Als je een tafel hebt met meerdere UNIQUE beperkingskolommen, en sommige staan ​​null-waarden toe, terwijl andere dat niet doen, kan dit argument van invloed zijn op welke wordt beschouwd als de optimale unieke identifier. Zie voorbeeld 7 onderaan dit artikel voor een voorbeeld van wat ik bedoel.

Voorbeeld 4 – IDENTITEIT Kolom

De tabel in dit voorbeeld heeft geen primaire sleutel of een UNIQUE beperking, maar het heeft wel een IDENTITY kolom.

Dit is de code die is gebruikt om de tabel te maken:

CREATE TABLE Product (
  ProductId int IDENTITY, 
  ProductName varchar(500)
  );

Dus laten we nu sp_special_columns uitvoeren tegen die tafel:

EXEC sp_special_columns Product;

Resultaat:

(0 rows affected)

Het lijkt er dus op dat IDENTITY is niet genoeg om deze tafel uniek te identificeren.

Voorbeeld 5 – Primaire sleutel met meerdere kolommen

Hier is er een met een primaire sleutel met meerdere kolommen. In dit geval worden twee kolommen gebruikt voor de primaire sleutel.

Dit is de code die is gebruikt om de tabel te maken:

CREATE TABLE PersonProduct (
  PersonId int, 
  ProductId int,
   CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId)
  ); 

Dus laten we nu sp_special_columns uitvoeren tegen die tafel:

EXEC sp_special_columns PersonProduct;

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| 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               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Voorbeeld 6 – Primaire sleutel en UNIEKE beperking

Wat als er een primaire sleutel is en een UNIQUE beperking in dezelfde tabel?

Laten we eens kijken:

CREATE TABLE PersonEvent (
  PersonEventId int UNIQUE,
  PersonId int, 
  EventId int,
   CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId)
  );

Voer sp_special_columns uit tegen die tafel:

EXEC sp_special_columns PersonEvent;

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| 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               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

De primaire sleutel heeft gewonnen.

Wat als we de primaire sleutel en de UNIQUE . verwisselen belangrijke kolommen in de buurt?

OK, laten we daarvoor nog een hele tabel maken:

CREATE TABLE PersonEvent2 (
  PersonEventId int PRIMARY KEY,
  PersonId int UNIQUE, 
  EventId int UNIQUE
  ); 

Voer sp_special_columns uit tegen die tafel:

EXEC sp_special_columns PersonEvent2;

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | PersonEventId | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Dus de primaire sleutel won weer.

Voorbeeld 7 – Veel UNIEKE beperkingen

Wat als elke kolom heeft een UNIQUE beperking?

CREATE TABLE Event2 (
  EventId int UNIQUE, 
  EventName varchar(500) UNIQUE,
  StartDate date UNIQUE,
  EndDate date UNIQUE
  );

Voer sp_special_columns uit tegen die tafel:

EXEC sp_special_columns Event2;

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EndDate       | -9          | date        | 10          | 20       | NULL    | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Maar laten we eens kijken wat er gebeurt als we een van die kolommen instellen op NOT NULL , gebruik dan @nullable = 'O' :

DROP TABLE Event2;

CREATE TABLE Event2 (
  EventId int NOT NULL UNIQUE, 
  EventName varchar(500) UNIQUE,
  StartDate date UNIQUE,
  EndDate date UNIQUE
  );

Voer sp_special_columns uit met @nullable = 'O' :

EXEC sp_special_columns 
  Event2,
  @nullable = 'O'; 

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EventId       | 4           | int         | 10          | 4        | 0       | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Dus de kolom "niet nullable" is nu gekozen als de optimale unieke identifier.

Laten we nu sp_special_columns uitvoeren met @nullable = 'U' :

EXEC sp_special_columns 
  Event2,
  @nullable = 'U';

Resultaat:

+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
| SCOPE   | COLUMN_NAME   | DATA_TYPE   | TYPE_NAME   | PRECISION   | LENGTH   | SCALE   | PSEUDO_COLUMN   |
|---------+---------------+-------------+-------------+-------------+----------+---------+-----------------|
| 1       | EndDate       | -9          | date        | 10          | 20       | NULL    | 1               |
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+

Het is nu terug naar de vorige kolom.


  1. SQL Server-query - groepsgewijze vermenigvuldiging

  2. KRUIS/BUITEN TOEPASSEN in MySQL

  3. PostgreSQL:Wijzig OWNER op alle tafels tegelijk in PostgreSQL

  4. Is er een manier om de weergavedefinitie van een SQL Server op te halen met behulp van gewone ADO?