В SQL Server можете да използвате sp_special_columns
системна съхранена процедура за идентифициране на уникален идентификатор за таблицата. По-конкретно, той връща оптималния набор от колони, които уникално идентифицират ред в таблицата. Той също така връща колони, автоматично актуализирани, когато някоя стойност в реда се актуализира от транзакция.
sp_special_columns
е еквивалентен на SQLSpecialColumns в ODBC.
Ако няма колони, които могат уникално да идентифицират таблицата, наборът от резултати е празен.
Синтаксис
Синтаксисът е така:
sp_special_columns [ @table_name =] 'table_name' [ , [ @table_owner =] 'table_owner' ] [ , [ @qualifier =] 'qualifier' ] [ , [ @col_type =] 'col_type' ] [ , [ @scope =] 'обхват' ] [ , [ @nullable =] 'nullable' ] [ , [ @ODBCVer =] 'ODBCVer' ] [; ]
@table_name
е необходим аргумент. Другите са по избор. Вижте документацията на Microsoft за подробно обяснение на всеки аргумент.
Пример 1 – Колона с първичен ключ
Ето основен пример срещу таблица с колона с първичен ключ, наречена PersonId :
EXEC sp_special_columns Лице;
Може да се изпълнява и по следния начин:
EXEC sp_special_columns @table_name ='Лице';
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
В този случай колоната с първичен ключ се връща. Знам, че това е колоната с първичен ключ, защото създадох таблицата със следния код:
СЪЗДАВАНЕ НА ТАБЛИЦА Лице (PersonId int първичен ключ, PersonName varchar(500) );
Така че изглежда, че съхранената процедура всъщност е върнала оптималната колона, която уникално идентифицира тази таблица.
Пример 2 – УНИКАЛНА колона
Таблицата в този пример няма първичен ключ, но има UNIQUE
ограничение.
Ето кода, използван за създаване на таблицата:
СЪЗДАВАЙТЕ ТАБЛИЦА събитие ( EventId int UNIQUE, EventName varchar(500) );
Така че нека сега изпълним sp_special_columns
срещу тази таблица:
EXEC sp_special_columns събитие;
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | EventId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
В този случай колоната с UNIQUE
ограничението се счита за оптимален уникален идентификатор.
Това обаче не означава непременно, че някои колона, ограничена от UNIQUE
ограничението автоматично ще се квалифицира като уникален идентификатор. Резултатът може да зависи от това как се третират нулевите стойности.
Пример 3 – Аргументът @nullable
Можете да използвате @nullable
аргумент, за да укажете дали специалните колони могат да приемат нулева стойност.
Тук стартирам отново същия код, освен че този път използвам @nullable = 'O'
.
EXEC sp_special_columns събитие, @nullable ='O';
Резултат:
(0 засегнати реда)
Тук се използва @nullable = 'U'
EXEC sp_special_columns събитие, @nullable ='U';
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | EventId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
O
определя специални колони, които не позволяват нулеви стойности. U
определя колони, които са частично нулеви. U
е стойността по подразбиране.
Ето какво се случва, ако създам колоната като NOT NULL
:
DROP TABLE Event;CREATE TABLE Event ( EventId int NOT NULL UNIQUE, EventName varchar(500) );EXEC sp_special_columns Събитие, @nullable ='U';EXEC sp_special_columns Събитие, @'nullable;
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | EventId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+(1 ред засегнат)+--------+--------------+-------- -----+------------+------------+----------+----- ----+----------------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | EventId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+(1 ред засегнат)
Този път и двете O
и U
даде същия резултат.
Ако имате таблица с множество UNIQUE
колони с ограничение, а някои позволяват нулеви стойности, докато други не, този аргумент може да окаже влияние върху това кой се счита за оптимален уникален идентификатор. Вижте Пример 7 в долната част на тази статия за пример за това, което имам предвид.
Пример 4 – Колона ИДЕНТИЧНОСТ
Таблицата в този пример няма първичен ключ или UNIQUE
ограничение, но то има IDENTITY
колона.
Ето кода, използван за създаване на таблицата:
СЪЗДАВАНЕ НА ТАБЛИЦА Продукт ( ProductId int IDENTITY, ProductName varchar(500) );
Така че нека сега изпълним sp_special_columns
срещу тази таблица:
EXEC sp_special_columns продукт;
Резултат:
(0 засегнати реда)
Така че изглежда, че IDENTITY
не е достатъчно за еднозначно идентифициране на тази таблица.
Пример 5 – Многоколонен първичен ключ
Ето един с първичен ключ от няколко колони. В този случай две колони се използват за първичен ключ.
Ето кода, използван за създаване на таблицата:
СЪЗДАВАНЕ НА ТАБЛИЦА PersonProduct ( PersonId int, ProductId int, CONSTRAINT PK_PersonProduct ПРАВИЛЕН КЛЮЧ (PersonId, ProductId) );
Така че нека сега изпълним sp_special_columns
срещу тази таблица:
EXEC sp_special_columns PersonProduct;
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 || 1 | ProductId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
Пример 6 – Първичен ключ и УНИКАЛНО ограничение
Ами ако има първичен ключ и a UNIQUE
ограничение в същата таблица?
Нека разберем:
СЪЗДАВАНЕ НА ТАБЛИЦА PersonEvent (PersonEventId int UNIQUE, PersonId int, EventId int, CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId) );
Изпълнете sp_special_columns
срещу тази таблица:
EXEC sp_special_columns PersonEvent;
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 || 1 | EventId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
Първичният ключ спечели.
Ами ако сменим първичния ключ и UNIQUE
ключови колони наоколо?
Добре, нека създадем друга цяла таблица само за това:
СЪЗДАВАНЕ НА ТАБЛИЦА PersonEvent2 ( PersonEventId int PRIMARY KEY, PersonId int UNIQUE, EventId int UNIQUE );
Изпълнете sp_special_columns
срещу тази таблица:
EXEC sp_special_columns PersonEvent2;
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | PersonEventId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
Така първичният ключ отново спечели.
Пример 7 – Много УНИКАЛНИ ограничения
Ами ако всеки колоната има UNIQUE
ограничение?
CREATE TABLE Event2 ( EventId int UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Изпълнете sp_special_columns
срещу тази таблица:
EXEC sp_special_columns Event2;
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | Крайна дата | -9 | дата | 10 | 20 | NULL | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
Но нека видим какво ще се случи, ако зададем една от тези колони на NOT NULL
, след това използвайте @nullable = 'O'
:
DROP TABLE Event2;CREATE TABLE Event2 ( EventId int NOT NULL UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Изпълнете sp_special_columns
с @nullable = 'O'
:
EXEC sp_special_columns Event2, @nullable ='O';
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | EventId | 4 | int | 10 | 4 | 0 | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
Така че колоната „not nullable“ вече е избрана като оптимален уникален идентификатор.
Сега нека изпълним sp_special_columns
с @nullable = 'U'
:
EXEC sp_special_columns Event2, @nullable ='U';
Резултат:
+--------+--------------+------------+------ -------+------------+---------+--------+------- ----------+| ОБХВАТ | COLUMN_NAME | DATA_TYPE | TYPE_NAME | ТОЧНОСТ | ДЪЛЖИНА | МАЩАБ | PSEUDO_COLUMN ||--------+--------------+------------+------- ------+------------+---------+---------+-------- ---------|| 1 | Крайна дата | -9 | дата | 10 | 20 | NULL | 1 |+---------+--------------+------------+------- ------+------------+---------+---------+-------- ---------+
Сега се връща към предишната колона.