W SQL Server możesz użyć sp_special_columns
systemowa procedura składowana w celu zidentyfikowania unikalnego identyfikatora tabeli. W szczególności zwraca optymalny zestaw kolumn, które jednoznacznie identyfikują wiersz w tabeli. Zwraca również kolumny automatycznie aktualizowane, gdy dowolna wartość w wierszu jest aktualizowana przez transakcję.
sp_special_columns
jest odpowiednikiem SQLSpecialColumns w ODBC.
Jeśli nie ma kolumn, które mogłyby jednoznacznie identyfikować tabelę, zestaw wyników jest pusty.
Składnia
Składnia wygląda tak:
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 jest wymagany. Pozostałe są opcjonalne. Zapoznaj się z dokumentacją firmy Microsoft, aby uzyskać szczegółowe wyjaśnienie każdego argumentu.
Przykład 1 – Kolumna klucza podstawowego
Oto podstawowy przykład z tabelą z kolumną klucza podstawowego o nazwie PersonId :
EXEC sp_special_columns Person;
Można go również uruchomić w ten sposób:
EXEC sp_special_columns @table_name = 'Person';
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
W takim przypadku zwracana jest kolumna klucza podstawowego. Wiem, że to jest kolumna klucza podstawowego, ponieważ utworzyłem tabelę za pomocą następującego kodu:
CREATE TABLE Person ( PersonId int primary key, PersonName varchar(500) );
Wygląda więc na to, że procedura składowana faktycznie zwróciła optymalną kolumnę, która jednoznacznie identyfikuje tę tabelę.
Przykład 2 – UNIKALNA kolumna
Tabela w tym przykładzie nie ma klucza podstawowego, ale ma UNIQUE
ograniczenie.
Oto kod użyty do utworzenia tabeli:
CREATE TABLE Event ( EventId int UNIQUE, EventName varchar(500) );
Więc teraz wykonajmy sp_special_columns
przy tej tabeli:
EXEC sp_special_columns Event;
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
W tym przypadku kolumna z UNIQUE
ograniczenie jest uważane za optymalny unikalny identyfikator.
Nie musi to jednak oznaczać, że dowolne kolumna ograniczona przez UNIQUE
ograniczenie automatycznie zakwalifikuje się jako unikalny identyfikator. Wynik może zależeć od sposobu traktowania wartości null.
Przykład 3 – argument @nullable
Możesz użyć @nullable
argument, aby określić, czy kolumny specjalne mogą akceptować wartość null.
Tutaj ponownie uruchamiam ten sam kod, ale tym razem używam @nullable = 'O'
.
EXEC sp_special_columns Event, @nullable = 'O';
Wynik:
(0 rows affected)
Tutaj używa @nullable = 'U'
EXEC sp_special_columns Event, @nullable = 'U';
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
O
określa specjalne kolumny, które nie zezwalają na wartości null. U
określa kolumny, które częściowo dopuszczają wartość null. U
jest wartością domyślną.
Oto, co się stanie, jeśli utworzę kolumnę 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';
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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)
Tym razem zarówno O
i U
dał ten sam wynik.
Jeśli masz tabelę z wieloma UNIQUE
kolumny z ograniczeniami, a niektóre zezwalają na wartości null, podczas gdy inne nie, ten argument może mieć wpływ na to, który z nich jest uważany za optymalny unikalny identyfikator. Zobacz przykład 7 na dole tego artykułu, aby zobaczyć przykład tego, co mam na myśli.
Przykład 4 – Kolumna IDENTYFIKACJA
Tabela w tym przykładzie nie ma klucza podstawowego ani UNIQUE
ograniczenie, ale ma IDENTITY
kolumna.
Oto kod użyty do utworzenia tabeli:
CREATE TABLE Product ( ProductId int IDENTITY, ProductName varchar(500) );
Więc teraz wykonajmy sp_special_columns
przy tej tabeli:
EXEC sp_special_columns Product;
Wynik:
(0 rows affected)
Wygląda więc na to, że IDENTITY
nie wystarczy, aby jednoznacznie zidentyfikować tę tabelę.
Przykład 5 – Wielokolumnowy klucz podstawowy
Oto jeden z wielokolumnowym kluczem podstawowym. W tym przypadku dla klucza podstawowego używane są dwie kolumny.
Oto kod użyty do utworzenia tabeli:
CREATE TABLE PersonProduct ( PersonId int, ProductId int, CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId) );
Więc teraz wykonajmy sp_special_columns
przy tej tabeli:
EXEC sp_special_columns PersonProduct;
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Przykład 6 – Klucz podstawowy i UNIKALNE ograniczenie
A co, jeśli istnieje klucz podstawowy i UNIQUE
ograniczenie w tej samej tabeli?
Dowiedzmy się:
CREATE TABLE PersonEvent ( PersonEventId int UNIQUE, PersonId int, EventId int, CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId) );
Wykonaj sp_special_columns
przy tej tabeli:
EXEC sp_special_columns PersonEvent;
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Wygrał klucz podstawowy.
Co się stanie, jeśli zamienimy klucz podstawowy i UNIQUE
? kluczowe kolumny wokół?
OK, stwórzmy kolejny cały stół właśnie w tym celu:
CREATE TABLE PersonEvent2 ( PersonEventId int PRIMARY KEY, PersonId int UNIQUE, EventId int UNIQUE );
Wykonaj sp_special_columns
przy tej tabeli:
EXEC sp_special_columns PersonEvent2;
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonEventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Więc klucz główny znów wygrał.
Przykład 7 – Wiele UNIKALNYCH ograniczeń
Co jeśli co kolumna ma UNIQUE
ograniczenie?
CREATE TABLE Event2 ( EventId int UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Wykonaj sp_special_columns
przy tej tabeli:
EXEC sp_special_columns Event2;
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Ale zobaczmy, co się stanie, jeśli ustawimy jedną z tych kolumn na NOT NULL
, a następnie użyj @nullable = 'O'
:
DROP TABLE Event2; CREATE TABLE Event2 ( EventId int NOT NULL UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Wykonaj sp_special_columns
z @nullable = 'O'
:
EXEC sp_special_columns Event2, @nullable = 'O';
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Tak więc kolumna „not nullable” jest teraz wybrana jako optymalny unikalny identyfikator.
Teraz wykonajmy sp_special_columns
z @nullable = 'U'
:
EXEC sp_special_columns Event2, @nullable = 'U';
Wynik:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Teraz wróciłem do poprzedniej kolumny.