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.