V SQL Server můžete použít sp_special_columns
systémová uložená procedura k identifikaci jedinečného identifikátoru tabulky. Konkrétně vrací optimální sadu sloupců, které jednoznačně identifikují řádek v tabulce. Také vrací sloupce automaticky aktualizované, když je jakákoli hodnota v řádku aktualizována transakcí.
sp_special_columns
je ekvivalentní SQLSpecialColumns v ODBC.
Pokud neexistují žádné sloupce, které by mohly jednoznačně identifikovat tabulku, je sada výsledků prázdná.
Syntaxe
Syntaxe vypadá takto:
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 je vyžadován. Ostatní jsou volitelné. Podrobné vysvětlení každého argumentu naleznete v dokumentaci společnosti Microsoft.
Příklad 1 – Sloupec primárního klíče
Zde je základní příklad proti tabulce se sloupcem primárního klíče s názvem PersonId :
EXEC sp_special_columns Person;
Lze jej spustit také takto:
EXEC sp_special_columns @table_name = 'Person';
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
V tomto případě je vrácen sloupec primárního klíče. Vím, že toto je sloupec primárního klíče, protože jsem vytvořil tabulku s následujícím kódem:
CREATE TABLE Person ( PersonId int primary key, PersonName varchar(500) );
Zdá se tedy, že uložená procedura ve skutečnosti vrátila optimální sloupec, který tuto tabulku jednoznačně identifikuje.
Příklad 2 – UNIKÁTNÍ sloupec
Tabulka v tomto příkladu nemá primární klíč, ale má UNIQUE
omezení.
Zde je kód použitý k vytvoření tabulky:
CREATE TABLE Event ( EventId int UNIQUE, EventName varchar(500) );
Nyní tedy spusťte sp_special_columns
proti této tabulce:
EXEC sp_special_columns Event;
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
V tomto případě sloupec s UNIQUE
omezení je považováno za optimální jedinečný identifikátor.
To však nutně neznamená, že jakýkoli sloupec omezený UNIQUE
omezení se automaticky kvalifikuje jako jedinečný identifikátor. Výsledek může záviset na tom, jak se zachází s hodnotami null.
Příklad 3 – Argument @nullable
Můžete použít @nullable
argument určující, zda mohou speciální sloupce přijímat hodnotu null.
Zde znovu spustím stejný kód, ale tentokrát používám @nullable = 'O'
.
EXEC sp_special_columns Event, @nullable = 'O';
Výsledek:
(0 rows affected)
Zde se používá @nullable = 'U'
EXEC sp_special_columns Event, @nullable = 'U';
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
O
určuje speciální sloupce, které nepovolují hodnoty null. U
určuje sloupce, které mohou částečně obsahovat hodnotu Null. U
je výchozí hodnota.
Zde je to, co se stane, když vytvořím sloupec jako 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';
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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)
Tentokrát oba O
a U
přinesl stejný výsledek.
Pokud máte tabulku s více UNIQUE
sloupce omezení a některé umožňují hodnoty null, zatímco jiné nikoli, může mít tento argument vliv na to, který z nich je považován za optimální jedinečný identifikátor. Viz příklad 7 ve spodní části tohoto článku, kde je příklad toho, co mám na mysli.
Příklad 4 – Sloupec IDENTITY
Tabulka v tomto příkladu nemá primární klíč ani UNIQUE
omezení, ale má IDENTITY
sloupec.
Zde je kód použitý k vytvoření tabulky:
CREATE TABLE Product ( ProductId int IDENTITY, ProductName varchar(500) );
Nyní tedy spusťte sp_special_columns
proti této tabulce:
EXEC sp_special_columns Product;
Výsledek:
(0 rows affected)
Zdá se tedy, že IDENTITY
nestačí k jedinečné identifikaci této tabulky.
Příklad 5 – Primární klíč s více sloupci
Zde je jeden s vícesloupcovým primárním klíčem. V tomto případě jsou pro primární klíč použity dva sloupce.
Zde je kód použitý k vytvoření tabulky:
CREATE TABLE PersonProduct ( PersonId int, ProductId int, CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId) );
Nyní tedy spusťte sp_special_columns
proti této tabulce:
EXEC sp_special_columns PersonProduct;
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Příklad 6 – Primární klíč a UNIKÁTNÍ omezení
Co když existuje primární klíč a UNIQUE
omezení ve stejné tabulce?
Pojďme to zjistit:
CREATE TABLE PersonEvent ( PersonEventId int UNIQUE, PersonId int, EventId int, CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId) );
Spusťte sp_special_columns
proti této tabulce:
EXEC sp_special_columns PersonEvent;
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Vyhrál primární klíč.
Co když změníme primární klíč a UNIQUE
klíčové sloupce kolem?
OK, pojďme vytvořit další celou tabulku jen pro to:
CREATE TABLE PersonEvent2 ( PersonEventId int PRIMARY KEY, PersonId int UNIQUE, EventId int UNIQUE );
Spusťte sp_special_columns
proti této tabulce:
EXEC sp_special_columns PersonEvent2;
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonEventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Primární klíč tedy opět zvítězil.
Příklad 7 – Mnoho UNIKÁTNÍCH omezení
Co když každý sloupec má UNIQUE
omezení?
CREATE TABLE Event2 ( EventId int UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Spusťte sp_special_columns
proti této tabulce:
EXEC sp_special_columns Event2;
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Ale podívejme se, co se stane, když jeden z těchto sloupců nastavíme na NOT NULL
a poté použijte @nullable = 'O'
:
DROP TABLE Event2; CREATE TABLE Event2 ( EventId int NOT NULL UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Spusťte sp_special_columns
s @nullable = 'O'
:
EXEC sp_special_columns Event2, @nullable = 'O';
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Sloupec „not nullable“ je tedy nyní zvolen jako optimální jedinečný identifikátor.
Nyní provedeme sp_special_columns
s @nullable = 'U'
:
EXEC sp_special_columns Event2, @nullable = 'U';
Výsledek:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Nyní je zpět k předchozímu sloupci.