In SQL Server puoi usare sp_special_columns
stored procedure di sistema per identificare un identificatore univoco per la tabella. In particolare, restituisce l'insieme ottimale di colonne che identificano in modo univoco una riga nella tabella. Restituisce anche colonne aggiornate automaticamente quando qualsiasi valore nella riga viene aggiornato da una transazione.
sp_special_columns
è equivalente a SQLSpecialColumns in ODBC.
Se non sono presenti colonne che possono identificare in modo univoco la tabella, il set di risultati è vuoto.
Sintassi
La sintassi è questa:
sp_special_columns [ @table_name = ] 'table_name' [ , [ @table_owner = ] 'table_owner' ] [ , [ @qualifier = ] 'qualifier' ] [ , [ @col_type = ] 'col_type' ] [ , [ @scope = ] 'scope' ] [ , [ @nullable = ] 'nullable' ] [ , [ @ODBCVer = ] 'ODBCVer' ] [ ; ]
Il @table_name
argomentazione è richiesta. Gli altri sono facoltativi. Consulta la documentazione Microsoft per una spiegazione dettagliata di ciascun argomento.
Esempio 1 – Colonna chiave primaria
Ecco un esempio di base su una tabella con una colonna di chiave primaria denominata PersonId :
EXEC sp_special_columns Person;
Può anche essere eseguito in questo modo:
EXEC sp_special_columns @table_name = 'Person';
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
In questo caso, viene restituita la colonna della chiave primaria. So che questa è la colonna della chiave primaria, perché ho creato la tabella con il seguente codice:
CREATE TABLE Person ( PersonId int primary key, PersonName varchar(500) );
Quindi sembra che la procedura memorizzata abbia effettivamente restituito la colonna ottimale che identifica in modo univoco questa tabella.
Esempio 2 – Colonna UNICA
La tabella in questo esempio non ha una chiave primaria, ma ha un UNIQUE
vincolo.
Ecco il codice utilizzato per creare la tabella:
CREATE TABLE Event ( EventId int UNIQUE, EventName varchar(500) );
Quindi ora eseguiamo sp_special_columns
contro quel tavolo:
EXEC sp_special_columns Event;
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
In questo caso, la colonna con UNIQUE
vincolo è considerato l'identificatore univoco ottimale.
Tuttavia, questo non significa necessariamente che qualsiasi colonna vincolata da un UNIQUE
vincolo si qualificherà automaticamente come identificatore univoco. Il risultato può dipendere da come vengono trattati i valori Null.
Esempio 3 – L'argomento @nullable
Puoi usare il @nullable
argomento per specificare se le colonne speciali possono accettare un valore null.
Qui, eseguo di nuovo lo stesso codice, tranne che questa volta uso @nullable = 'O'
.
EXEC sp_special_columns Event, @nullable = 'O';
Risultato:
(0 rows affected)
Qui sta usando @nullable = 'U'
EXEC sp_special_columns Event, @nullable = 'U';
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
O
specifica colonne speciali che non consentono valori null. U
specifica le colonne parzialmente annullabili. U
è il valore predefinito.
Ecco cosa succede se creo la colonna come 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';
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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)
Questa volta entrambi O
e U
prodotto lo stesso risultato.
Se hai una tabella con più UNIQUE
colonne di vincolo e alcune consentono valori null mentre altre no, questo argomento può avere un impatto su quale è considerato l'identificatore univoco ottimale. Vedi l'Esempio 7 in fondo a questo articolo per un esempio di cosa intendo.
Esempio 4 – Colonna IDENTITÀ
La tabella in questo esempio non ha una chiave primaria o un UNIQUE
vincolo, ma ha un IDENTITY
colonna.
Ecco il codice utilizzato per creare la tabella:
CREATE TABLE Product ( ProductId int IDENTITY, ProductName varchar(500) );
Quindi ora eseguiamo sp_special_columns
contro quel tavolo:
EXEC sp_special_columns Product;
Risultato:
(0 rows affected)
Quindi sembra che IDENTITY
non è sufficiente per identificare in modo univoco questa tabella.
Esempio 5 – Chiave primaria multicolonna
Eccone uno con una chiave primaria multicolonna. In questo caso vengono utilizzate due colonne per la chiave primaria.
Ecco il codice utilizzato per creare la tabella:
CREATE TABLE PersonProduct ( PersonId int, ProductId int, CONSTRAINT PK_PersonProduct PRIMARY KEY (PersonId, ProductId) );
Quindi ora eseguiamo sp_special_columns
contro quel tavolo:
EXEC sp_special_columns PersonProduct;
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Esempio 6 – Chiave primaria e vincolo UNICO
Cosa succede se c'è una chiave primaria e un UNIQUE
vincolo nella stessa tabella?
Scopriamolo:
CREATE TABLE PersonEvent ( PersonEventId int UNIQUE, PersonId int, EventId int, CONSTRAINT PK_PersonEvent PRIMARY KEY (PersonId, EventId) );
Esegui sp_special_columns
contro quel tavolo:
EXEC sp_special_columns PersonEvent;
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | 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 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
La chiave primaria ha vinto.
E se cambiassimo la chiave primaria e UNIQUE
colonne chiave intorno?
OK, creiamo un'altra intera tabella solo per questo:
CREATE TABLE PersonEvent2 ( PersonEventId int PRIMARY KEY, PersonId int UNIQUE, EventId int UNIQUE );
Esegui sp_special_columns
contro quel tavolo:
EXEC sp_special_columns PersonEvent2;
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | PersonEventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Quindi la chiave primaria ha vinto di nuovo.
Esempio 7 – Molti Vincoli UNICI
E se ogni la colonna ha un UNIQUE
vincolo?
CREATE TABLE Event2 ( EventId int UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Esegui sp_special_columns
contro quel tavolo:
EXEC sp_special_columns Event2;
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Ma vediamo cosa succede se impostiamo una di queste colonne su NOT NULL
, quindi usa @nullable = 'O'
:
DROP TABLE Event2; CREATE TABLE Event2 ( EventId int NOT NULL UNIQUE, EventName varchar(500) UNIQUE, StartDate date UNIQUE, EndDate date UNIQUE );
Esegui sp_special_columns
con @nullable = 'O'
:
EXEC sp_special_columns Event2, @nullable = 'O';
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EventId | 4 | int | 10 | 4 | 0 | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Quindi la colonna "non nullable" è ora scelta come identificatore univoco ottimale.
Ora eseguiamo sp_special_columns
con @nullable = 'U'
:
EXEC sp_special_columns Event2, @nullable = 'U';
Risultato:
+---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+ | SCOPE | COLUMN_NAME | DATA_TYPE | TYPE_NAME | PRECISION | LENGTH | SCALE | PSEUDO_COLUMN | |---------+---------------+-------------+-------------+-------------+----------+---------+-----------------| | 1 | EndDate | -9 | date | 10 | 20 | NULL | 1 | +---------+---------------+-------------+-------------+-------------+----------+---------+-----------------+
Ora si torna alla colonna precedente.