Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

So finden Sie den optimalen eindeutigen Bezeichner in einer Tabelle in SQL Server:sp_special_columns

In SQL Server können Sie die sp_special_columns verwenden gespeicherte Systemprozedur, um einen eindeutigen Bezeichner für die Tabelle zu identifizieren. Insbesondere gibt es den optimalen Satz von Spalten zurück, die eine Zeile in der Tabelle eindeutig identifizieren. Es gibt auch Spalten zurück, die automatisch aktualisiert werden, wenn irgendein Wert in der Zeile durch eine Transaktion aktualisiert wird.

sp_special_columns entspricht SQLSpecialColumns in ODBC.

Wenn es keine Spalten gibt, die die Tabelle eindeutig identifizieren können, ist die Ergebnismenge leer.

Syntax

Die Syntax lautet wie folgt:

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

Der @table_name Argument ist erforderlich. Die anderen sind optional. Eine detaillierte Erklärung jedes Arguments finden Sie in der Microsoft-Dokumentation.

Beispiel 1 – Primärschlüsselspalte

Hier ist ein einfaches Beispiel für eine Tabelle mit einer Primärschlüsselspalte namens PersonId :

EXEC sp_special_columns Person;

Es kann auch so ausgeführt werden:

EXEC sp_special_columns @table_name = 'Person';

Ergebnis:

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

In diesem Fall wird die Primärschlüsselspalte zurückgegeben. Ich weiß, dass dies die Primärschlüsselspalte ist, weil ich die Tabelle mit dem folgenden Code erstellt habe:

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

Es scheint also, dass die gespeicherte Prozedur tatsächlich die optimale Spalte zurückgegeben hat, die diese Tabelle eindeutig identifiziert.

Beispiel 2 – UNIQUE-Spalte

Die Tabelle in diesem Beispiel hat keinen Primärschlüssel, aber einen UNIQUE Einschränkung.

Hier ist der Code, der zum Erstellen der Tabelle verwendet wurde:

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

Lassen Sie uns nun sp_special_columns ausführen gegen diese Tabelle:

EXEC sp_special_columns Event;

Ergebnis:

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

In diesem Fall die Spalte mit dem UNIQUE Constraint gilt als optimale eindeutige Kennung.

Dies bedeutet jedoch nicht unbedingt, dass irgendwelche Spalte eingeschränkt durch einen UNIQUE Einschränkung wird automatisch als eindeutiger Bezeichner qualifiziert. Das Ergebnis kann davon abhängen, wie Nullwerte behandelt werden.

Beispiel 3 – Das @nullable-Argument

Sie können den @nullable verwenden -Argument, um anzugeben, ob die speziellen Spalten einen Nullwert akzeptieren können.

Hier führe ich denselben Code noch einmal aus, außer dass ich dieses Mal @nullable = 'O' verwende .

EXEC sp_special_columns 
  Event, 
  @nullable = 'O';

Ergebnis:

(0 rows affected)

Hier wird @nullable = 'U' verwendet

EXEC sp_special_columns 
  Event, 
  @nullable = 'U';

Ergebnis:

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

O gibt spezielle Spalten an, die keine Nullwerte zulassen. U gibt Spalten an, die teilweise nullfähig sind. U ist der Standardwert.

Folgendes passiert, wenn ich die Spalte als NOT NULL erstelle :

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';

Ergebnis:

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

Diesmal beides O und U brachte das gleiche Ergebnis.

Wenn Sie eine Tabelle mit mehreren UNIQUE haben Constraint-Spalten, und einige erlauben Nullwerte, während andere dies nicht tun, kann dieses Argument einen Einfluss darauf haben, welcher als optimaler eindeutiger Bezeichner angesehen wird. Siehe Beispiel 7 am Ende dieses Artikels für ein Beispiel dafür, was ich meine.

Beispiel 4 – Identitätsspalte

Die Tabelle in diesem Beispiel hat keinen Primärschlüssel oder einen UNIQUE Einschränkung, aber es hat eine IDENTITY Spalte.

Hier ist der Code, der zum Erstellen der Tabelle verwendet wurde:

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

Lassen Sie uns nun sp_special_columns ausführen gegen diese Tabelle:

EXEC sp_special_columns Product;

Ergebnis:

(0 rows affected)

Es scheint also, dass IDENTITY reicht nicht aus, um diese Tabelle eindeutig zu identifizieren.

Beispiel 5 – Mehrspaltiger Primärschlüssel

Hier ist einer mit einem mehrspaltigen Primärschlüssel. In diesem Fall werden zwei Spalten für den Primärschlüssel verwendet.

Hier ist der Code, der zum Erstellen der Tabelle verwendet wurde:

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

Lassen Sie uns nun sp_special_columns ausführen gegen diese Tabelle:

EXEC sp_special_columns PersonProduct;

Ergebnis:

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

Beispiel 6 – Primärschlüssel und UNIQUE-Einschränkung

Was ist, wenn es einen Primärschlüssel und gibt ein UNIQUE Constraint in derselben Tabelle?

Finden wir es heraus:

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

Führen Sie sp_special_columns aus gegen diese Tabelle:

EXEC sp_special_columns PersonEvent;

Ergebnis:

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

Der Primärschlüssel hat gewonnen.

Was ist, wenn wir den Primärschlüssel und den UNIQUE vertauschen? Schlüsselspalten herum?

OK, erstellen wir dafür eine weitere ganze Tabelle:

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

Führen Sie sp_special_columns aus gegen diese Tabelle:

EXEC sp_special_columns PersonEvent2;

Ergebnis:

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

Also hat der Primärschlüssel wieder gewonnen.

Beispiel 7 – Viele EINZIGARTIGE Beschränkungen

Was wäre, wenn alle Spalte hat einen UNIQUE Einschränkung?

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

Führen Sie sp_special_columns aus gegen diese Tabelle:

EXEC sp_special_columns Event2;

Ergebnis:

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

Aber mal sehen, was passiert, wenn wir eine dieser Spalten auf NOT NULL setzen , dann verwenden Sie @nullable = 'O' :

DROP TABLE Event2;

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

Führen Sie sp_special_columns aus mit @nullable = 'O' :

EXEC sp_special_columns 
  Event2,
  @nullable = 'O'; 

Ergebnis:

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

Daher wird die Spalte „not nullable“ jetzt als optimaler eindeutiger Bezeichner ausgewählt.

Lassen Sie uns nun sp_special_columns ausführen mit @nullable = 'U' :

EXEC sp_special_columns 
  Event2,
  @nullable = 'U';

Ergebnis:

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

Es geht jetzt zurück zur vorherigen Spalte.