sql >> Databáze >  >> RDS >> Sqlserver

Jak najít optimální jedinečný identifikátor v tabulce na serveru SQL Server:sp_special_columns

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.


  1. Automatické mazání zaseknutých procesů v MS SQL Server

  2. Pivoting, Unpivoting a Spliting columns in Power BI Query Editor

  3. Děláte tyto chyby při používání SQL CURSOR?

  4. Nasazení MySQL, MariaDB, Percona Server, MongoDB nebo PostgreSQL – snadné s ClusterControl