Ci sono spesso molti modi per fare la stessa cosa (o simili) in SQL Server. Un esempio calzante è il recupero di tutte le chiavi primarie da un database (o anche solo della chiave primaria per una determinata tabella).
Questo articolo presenta undici diversi approcci per recuperare le informazioni sulla chiave primaria in SQL Server.
Alcuni di questi saranno più utili di altri, a seconda della tua situazione esatta.
Esempio 1:la stored procedure di sistema sp_pkeys
Se vuoi solo la chiave primaria per una determinata tabella, sp_pkeys
la procedura memorizzata di sistema è probabilmente il modo più rapido e semplice per farlo. Per fare ciò, è sufficiente passare il nome della tabella alla procedura.
In questo modo:
EXEC sp_pkeys Artists;
Risultato (usando l'output verticale):
TABLE_QUALIFIER | Music TABLE_OWNER | dbo TABLE_NAME | Artists COLUMN_NAME | ArtistId KEY_SEQ | 1 PK_NAME | PK__Artists__25706B50FCD918B1
In questo caso ho richiesto la chiave primaria agli Artisti tavolo. Restituisce il nome della chiave primaria ( PK__Artists__25706B50FCD918B1 ), il nome del database ( Music ), il nome della tabella, il nome della colonna ( ArtistId ), più altre informazioni.
In alternativa, avrei potuto specificare esplicitamente tutti gli argomenti per ottenere lo stesso risultato:
EXEC sp_pkeys @table_name = Artists, @table_owner = dbo, @table_qualifier = Music;
Esempio 2 – La vista di sistema KEY_COLUMN_USAGE
Il INFORMATION_SCHEMA.KEY_COLUMN_USAGE
la vista di sistema restituisce una riga per ogni colonna vincolata come chiave nel database corrente. Pertanto otterrai anche chiavi esterne restituite con questa vista.
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
Risultato:
+--------------+---------------+-------------------------------+ | TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | |--------------+---------------+-------------------------------| | Albums | ArtistId | FK_Albums_Artists | | Albums | GenreId | FK_Albums_Genres | | Albums | AlbumId | PK__Albums__97B4BE379FC780BD | | Artists | ArtistId | PK__Artists__25706B50FCD918B1 | | Genres | GenreId | PK__Genres__0385057E88BB96F8 | +--------------+---------------+-------------------------------+
Possiamo vedere che questo restituisce vincoli da tutte le tabelle. Potremmo anche aggiungere un WHERE
clausola per restringere i risultati a una tabella specifica.
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'Artists';
Risultato:
+--------------+---------------+-------------------------------+ | TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | |--------------+---------------+-------------------------------| | Artists | ArtistId | PK__Artists__25706B50FCD918B1 | +--------------+---------------+-------------------------------+
In questi esempi, ho ristretto i risultati solo alle colonne della vista che mi interessano, ma puoi anche usare l'asterisco (*
) carattere jolly per restituire tutte le colonne.
SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'Artists';
Risultato (usando l'output verticale):
CONSTRAINT_CATALOG | Music CONSTRAINT_SCHEMA | dbo CONSTRAINT_NAME | PK__Artists__25706B50FCD918B1 TABLE_CATALOG | Music TABLE_SCHEMA | dbo TABLE_NAME | Artists COLUMN_NAME | ArtistId ORDINAL_POSITION | 1
Esempio 3 – Vista del sistema CONSTRAINT_COLUMN_USAGE
Questo è simile all'esempio precedente. Il INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
la vista di sistema restituisce una riga per ogni colonna del database corrente che ha un vincolo definito sulla colonna. Come con INFORMATION_SCHEMA.KEY_COLUMN_USAGE
riceverai anche chiavi esterne restituite con questa vista. Tuttavia, INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
non si limita ai soli vincoli chiave.
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE;
Risultato:
+--------------+---------------+-------------------------------+ | TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | |--------------+---------------+-------------------------------| | Albums | ArtistId | FK_Albums_Artists | | Albums | GenreId | FK_Albums_Genres | | Albums | AlbumId | PK__Albums__97B4BE379FC780BD | | Artists | ArtistId | PK__Artists__25706B50FCD918B1 | | Genres | GenreId | PK__Genres__0385057E88BB96F8 | +--------------+---------------+-------------------------------+
Puoi usare un WHERE
clausola per restituire solo una tabella o una colonna specifica:
SELECT TABLE_NAME, COLUMN_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE COLUMN_NAME = 'ArtistId';
Risultato:
+--------------+---------------+-------------------------------+ | TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | |--------------+---------------+-------------------------------| | Albums | ArtistId | FK_Albums_Artists | | Artists | ArtistId | PK__Artists__25706B50FCD918B1 | +--------------+---------------+-------------------------------+
In questo caso ho specificato un nome di colonna, quindi ha restituito tutti i vincoli sulle colonne con quel nome. A quanto pare, il database utilizza lo stesso nome di colonna in due tabelle diverse. Uno ha un vincolo di chiave esterna, l'altro una chiave primaria. Pertanto vengono restituite entrambe le righe.
Anche in questo caso, puoi utilizzare l'asterisco (*
) carattere jolly per restituire tutte le colonne.
SELECT * FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE TABLE_NAME = 'Artists';
Risultato (usando l'output verticale):
TABLE_CATALOG | Music TABLE_SCHEMA | dbo TABLE_NAME | Artists COLUMN_NAME | ArtistId CONSTRAINT_CATALOG | Music CONSTRAINT_SCHEMA | dbo CONSTRAINT_NAME | PK__Artists__25706B50FCD918B1
In questo esempio ho limitato l'output ai soli vincoli su una tabella specifica.
Esempio 4 – Vista del sistema CONSTRAINT_TABLE_USAGE
Il INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE
la vista di sistema restituisce una riga per ogni tabella nel database corrente che ha un vincolo definito sulla tabella.
SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE;
Risultato:
+--------------+-------------------------------+ | TABLE_NAME | CONSTRAINT_NAME | |--------------+-------------------------------| | Artists | PK__Artists__25706B50FCD918B1 | | Genres | PK__Genres__0385057E88BB96F8 | | Albums | PK__Albums__97B4BE379FC780BD | | Albums | FK_Albums_Artists | | Albums | FK_Albums_Genres | +--------------+-------------------------------+
Questa vista non restituisce il nome o i nomi di colonna su cui vengono utilizzati i vincoli, quindi potrebbe non essere così utile per te, a seconda delle tue esigenze.
Ecco un esempio che mostra tutti i dati restituiti da questa vista per i Generi tabella:
SELECT * FROM INFORMATION_SCHEMA.CONSTRAINT_TABLE_USAGE WHERE TABLE_NAME = 'Genres';
Risultato:
TABLE_CATALOG | Music TABLE_SCHEMA | dbo TABLE_NAME | Genres CONSTRAINT_CATALOG | Music CONSTRAINT_SCHEMA | dbo CONSTRAINT_NAME | PK__Genres__0385057E88BB96F8
Esempio 5 – La vista del sistema TABLE_CONSTRAINTS
Il INFORMATION_SCHEMA.TABLE_CONSTRAINTS
la vista di sistema restituisce una riga per ogni vincolo di tabella nel database corrente.
SELECT TABLE_NAME, CONSTRAINT_NAME, CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS;
Risultato:
+--------------+-------------------------------+-------------------+ | TABLE_NAME | CONSTRAINT_NAME | CONSTRAINT_TYPE | |--------------+-------------------------------+-------------------| | Artists | PK__Artists__25706B50FCD918B1 | PRIMARY KEY | | Genres | PK__Genres__0385057E88BB96F8 | PRIMARY KEY | | Albums | PK__Albums__97B4BE379FC780BD | PRIMARY KEY | | Albums | FK_Albums_Artists | FOREIGN KEY | | Albums | FK_Albums_Genres | FOREIGN KEY | +--------------+-------------------------------+-------------------+
Questa vista non fornisce il nome della colonna, ma fornisce il tipo di vincolo. Pertanto, puoi restringere i risultati alle sole chiavi primarie:
SELECT TABLE_NAME, CONSTRAINT_NAME, CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'PRIMARY KEY';
Risultato:
+--------------+-------------------------------+-------------------+ | TABLE_NAME | CONSTRAINT_NAME | CONSTRAINT_TYPE | |--------------+-------------------------------+-------------------| | Artists | PK__Artists__25706B50FCD918B1 | PRIMARY KEY | | Genres | PK__Genres__0385057E88BB96F8 | PRIMARY KEY | | Albums | PK__Albums__97B4BE379FC780BD | PRIMARY KEY | +--------------+-------------------------------+-------------------+
Ecco un esempio che utilizza un carattere jolly (*
) per restituire tutti i dati per i vincoli sugli
Artisti
tabella:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'Artists';
Risultato:
CONSTRAINT_CATALOG | Music CONSTRAINT_SCHEMA | dbo CONSTRAINT_NAME | PK__Artists__25706B50FCD918B1 TABLE_CATALOG | Music TABLE_SCHEMA | dbo TABLE_NAME | Artists CONSTRAINT_TYPE | PRIMARY KEY IS_DEFERRABLE | NO INITIALLY_DEFERRED | NO
Esempio 6 – La vista di sistema key_constraints
Il sys.key_constraints
la vista di sistema contiene una riga per ogni oggetto che è una chiave primaria o un vincolo univoco. Pertanto potremmo utilizzare il codice seguente per restituire tutti i vincoli di chiave primaria nel database, insieme alla tabella pertinente per ciascuna chiave primaria:
SELECT OBJECT_NAME(parent_object_id) AS 'Table', name FROM sys.key_constraints WHERE type = 'PK';
Risultato:
+---------+-------------------------------+ | Table | name | |---------+-------------------------------| | Artists | PK__Artists__25706B50FCD918B1 | | Genres | PK__Genres__0385057E88BB96F8 | | Albums | PK__Albums__97B4BE379FC780BD | +---------+-------------------------------+
Ovviamente puoi rimuovere il WHERE
clausola per restituire entrambe le chiavi primarie e chiavi univoche.
L'esempio precedente utilizza OBJECT_NAME()
funzione per restituire il nome della tabella padre, anziché il relativo object_id. Se non ho usato OBJECT_NAME()
funzione, il risultato sarebbe stato simile a questo:
SELECT parent_object_id, name FROM sys.key_constraints WHERE type = 'PK';
Risultato:
+--------------------+-------------------------------+ | parent_object_id | name | |--------------------+-------------------------------| | 885578193 | PK__Artists__25706B50FCD918B1 | | 917578307 | PK__Genres__0385057E88BB96F8 | | 949578421 | PK__Albums__97B4BE379FC780BD | +--------------------+-------------------------------+
Il
parent_object_id
viene restituito al posto del nome dell'oggetto padre. Il OBJECT_NAME()
La funzione rende molto più facile capire a quale tabella viene applicata ciascuna chiave.
Ecco un esempio in cui utilizzo il carattere jolly (*
) per restituire tutte le colonne per la chiave primaria negli
Album
tabella:
SELECT * FROM sys.key_constraints WHERE type = 'PK' AND OBJECT_NAME(parent_object_id) = 'Albums';
Risultato:
name | PK__Albums__97B4BE379FC780BD object_id | 965578478 principal_id | NULL schema_id | 1 parent_object_id | 949578421 type | PK type_desc | PRIMARY_KEY_CONSTRAINT create_date | 2019-05-02 12:56:06.377 modify_date | 2019-05-02 12:56:06.377 is_ms_shipped | 0 is_published | 0 is_schema_published | 0 unique_index_id | 1 is_system_named | 1 is_enforced | 1
Esempio 7 – La vista di sistema di sys.objects
Il sys.objects
vista sistema contiene una riga per ogni oggetto definito dall'utente con ambito schema creato all'interno di un database. Quindi contiene le nostre tabelle e le chiavi primarie.
Possiamo prendere la query precedente e sostituire key_constraints
con objects
e otterremo lo stesso risultato:
SELECT OBJECT_NAME(parent_object_id) AS 'Table', name FROM sys.objects WHERE type = 'PK';
Risultato:
+---------+-------------------------------+ | Table | name | |---------+-------------------------------| | Artists | PK__Artists__25706B50FCD918B1 | | Genres | PK__Genres__0385057E88BB96F8 | | Albums | PK__Albums__97B4BE379FC780BD | +---------+-------------------------------+
Ecco un esempio che restituisce tutti i dati per il PK__Genres__0385057E88BB96F8 chiave primaria:
SELECT * FROM sys.objects WHERE name = 'PK__Genres__0385057E88BB96F8';
Risultato (usando l'output verticale):
name | PK__Genres__0385057E88BB96F8 object_id | 933578364 principal_id | NULL schema_id | 1 parent_object_id | 917578307 type | PK type_desc | PRIMARY_KEY_CONSTRAINT create_date | 2019-05-02 12:56:06.110 modify_date | 2019-05-02 12:56:06.110 is_ms_shipped | 0 is_published | 0 is_schema_published | 0
Esempio 8 – Vista del sistema REFERENTIAL_CONSTRAINTS
Questo è un po 'esagerato, ma potrebbe essere utile a seconda della situazione. E tecnicamente, restituisce (alcune) chiavi primarie.
Il INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
la vista di sistema restituisce una riga per ogni FOREIGN KEY
vincolo nel database corrente. Quindi il suo scopo è in realtà restituire chiavi esterne, non chiavi primarie. Tuttavia, questa visualizzazione può essere utile se si desidera visualizzare solo tutte le chiavi primarie a cui è associata una chiave esterna. Non è un metodo affidabile da utilizzare se vuoi vedere tutte le chiavi primarie indipendentemente dal fatto che sia associata una chiave esterna.
Ecco un esempio:
SELECT CONSTRAINT_NAME, UNIQUE_CONSTRAINT_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS;
Risultato:
+-------------------+-------------------------------+ | CONSTRAINT_NAME | UNIQUE_CONSTRAINT_NAME | |-------------------+-------------------------------| | FK_Albums_Artists | PK__Artists__25706B50FCD918B1 | | FK_Albums_Genres | PK__Genres__0385057E88BB96F8 | +-------------------+-------------------------------+
Come puoi vedere, questo restituisce solo quelle chiavi primarie che hanno una chiave esterna associata. Per essere più precisi, in realtà è il contrario:restituisce tutte le chiavi esterne, insieme al loro UNIQUE
associato vincolo.
Quindi, se confrontiamo questi risultati con i risultati degli esempi precedenti, possiamo vedere che vengono restituite solo due chiavi primarie (rispetto alle tre degli esempi precedenti). Questo perché una delle chiavi primarie in questo database ( PK__Albums__97B4BE379FC780BD ) non ha una chiave esterna associata.
Ecco un esempio che restituisce tutti i dati per le chiavi esterne di cui
PK__Artists__25706B50FCD918B1
è il UNIQUE
vincolo:
SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE UNIQUE_CONSTRAINT_NAME = 'PK__Artists__25706B50FCD918B1';
Risultato:
CONSTRAINT_CATALOG | Music CONSTRAINT_SCHEMA | dbo CONSTRAINT_NAME | FK_Albums_Artists UNIQUE_CONSTRAINT_CATALOG | Music UNIQUE_CONSTRAINT_SCHEMA | dbo UNIQUE_CONSTRAINT_NAME | PK__Artists__25706B50FCD918B1 MATCH_OPTION | SIMPLE UPDATE_RULE | NO ACTION DELETE_RULE | NO ACTION
In questo caso, viene restituita solo una chiave esterna.
Come accennato, questa visualizzazione serve principalmente a restituire informazioni sulla chiave esterna, quindi utilizzare questo metodo solo se si desidera visualizzare le informazioni sulla chiave esterna insieme alla chiave primaria associata. Non utilizzare questo metodo se vuoi vedere tutte le chiavi primarie indipendentemente dal fatto che abbiano una chiave esterna associata.
Esempio 9 – La stored procedure di sistema sp_fkeys
Questo metodo è simile al metodo precedente, nel senso che restituisce informazioni sulla chiave esterna. Restituisce anche la chiave primaria associata a ciascuna chiave esterna.
Esempio:
EXEC sp_fkeys Artists;
Risultato (usando l'output verticale):
PKTABLE_QUALIFIER | Music PKTABLE_OWNER | dbo PKTABLE_NAME | Artists PKCOLUMN_NAME | ArtistId FKTABLE_QUALIFIER | Music FKTABLE_OWNER | dbo FKTABLE_NAME | Albums FKCOLUMN_NAME | ArtistId KEY_SEQ | 1 UPDATE_RULE | 1 DELETE_RULE | 1 FK_NAME | FK_Albums_Artists PK_NAME | PK__Artists__25706B50FCD918B1 DEFERRABILITY | 7
Avrei potuto usare invece la seguente sintassi (o una combinazione di questi argomenti):
EXEC sp_fkeys @pktable_name = Artists, @pktable_owner = dbo, @pktable_qualifier = Music, @fktable_name = Albums, @fktable_owner = dbo, @fktable_qualifier = Music;
Come nell'esempio precedente, questo metodo non dovrebbe essere utilizzato per restituire tutte le chiavi primarie. Se una chiave primaria non ha una chiave esterna associata, non verrà restituita.
Esempio 10:la stored procedure di sistema sp_helpconstraint
Il sp_helpconstraint
la procedura memorizzata di sistema restituisce un elenco di tutti i tipi di vincolo, il nome definito dall'utente o fornito dal sistema, le colonne su cui sono stati definiti e l'espressione che definisce il vincolo (per DEFAULT
e CHECK
solo vincoli).
Pertanto puoi usarlo per restituire informazioni sulle chiavi primarie nel tuo database.
Esempio:
EXEC sp_helpconstraint Albums;
Risultato:
+---------------+ | Object Name | |---------------| | Albums | +---------------+ -[ RECORD 1 ]------------------------- constraint_type | FOREIGN KEY constraint_name | FK_Albums_Artists delete_action | No Action update_action | No Action status_enabled | Enabled status_for_replication | Is_For_Replication constraint_keys | ArtistId -[ RECORD 2 ]------------------------- constraint_type | constraint_name | delete_action | update_action | status_enabled | status_for_replication | constraint_keys | REFERENCES Music.dbo.Artists (ArtistId) -[ RECORD 3 ]------------------------- constraint_type | FOREIGN KEY constraint_name | FK_Albums_Genres delete_action | No Action update_action | No Action status_enabled | Enabled status_for_replication | Is_For_Replication constraint_keys | GenreId -[ RECORD 4 ]------------------------- constraint_type | constraint_name | delete_action | update_action | status_enabled | status_for_replication | constraint_keys | REFERENCES Music.dbo.Genres (GenreId) -[ RECORD 5 ]------------------------- constraint_type | PRIMARY KEY (clustered) constraint_name | PK__Albums__97B4BE379FC780BD delete_action | (n/a) update_action | (n/a) status_enabled | (n/a) status_for_replication | (n/a) constraint_keys | AlbumId
Esempio 11 – La stored procedure di sistema sp_help
Il sp_help
la procedura memorizzata di sistema riporta informazioni su un oggetto database (qualsiasi oggetto elencato in sys.sysobjects
visualizzazione compatibilità), un tipo di dati definito dall'utente o un tipo di dati. Ciò include informazioni sulle chiavi primarie.
Quando lo esegui senza alcun argomento, fornisce informazioni sulle informazioni di riepilogo degli oggetti di tutti i tipi che esistono nel database corrente (cioè un lotto di informazioni).
Tuttavia, puoi fornire il nome di una tabella e restituirà informazioni su quella tabella. Anche in questo caso, riceverai molte informazioni restituite, ma tra queste ci saranno le informazioni chiave primarie.
Esempio:
EXEC sp_help Artists;
Risultato:
+---------+---------+------------+-------------------------+ | Name | Owner | Type | Created_datetime | |---------+---------+------------+-------------------------| | Artists | dbo | user table | 2019-05-02 12:56:05.840 | +---------+---------+------------+-------------------------+ -[ RECORD 1 ]------------------------- Column_name | ArtistId Type | int Computed | no Length | 4 Prec | 10 Scale | 0 Nullable | no TrimTrailingBlanks | (n/a) FixedLenNullInSource | (n/a) Collation | NULL -[ RECORD 2 ]------------------------- Column_name | ArtistName Type | nvarchar Computed | no Length | 510 Prec | Scale | Nullable | no TrimTrailingBlanks | (n/a) FixedLenNullInSource | (n/a) Collation | SQL_Latin1_General_CP1_CI_AS -[ RECORD 3 ]------------------------- Column_name | ActiveFrom Type | date Computed | no Length | 3 Prec | 10 Scale | 0 Nullable | yes TrimTrailingBlanks | (n/a) FixedLenNullInSource | (n/a) Collation | NULL +------------+--------+-------------+-----------------------+ | Identity | Seed | Increment | Not For Replication | |------------+--------+-------------+-----------------------| | ArtistId | 1 | 1 | 0 | +------------+--------+-------------+-----------------------+ +-------------------------------+ | RowGuidCol | |-------------------------------| | No rowguidcol column defined. | +-------------------------------+ +-----------------------------+ | Data_located_on_filegroup | |-----------------------------| | PRIMARY | +-----------------------------+ +-------------------------------+---------------------------------------------------+--------------+ | index_name | index_description | index_keys | |-------------------------------+---------------------------------------------------+--------------| | PK__Artists__25706B50FCD918B1 | clustered, unique, primary key located on PRIMARY | ArtistId | +-------------------------------+---------------------------------------------------+--------------+ -[ RECORD 1 ]------------------------- constraint_type | PRIMARY KEY (clustered) constraint_name | PK__Artists__25706B50FCD918B1 delete_action | (n/a) update_action | (n/a) status_enabled | (n/a) status_for_replication | (n/a) constraint_keys | ArtistId +--------------------------------------+ | Table is referenced by foreign key | |--------------------------------------| | Music.dbo.Albums: FK_Albums_Artists | +--------------------------------------+
Puoi anche fornire il nome di una chiave primaria per ottenere alcune informazioni di base su di essa:
EXEC sp_help PK__Artists__25706B50FCD918B1;
Risultato:
+-------------------------------+---------+-----------------+-------------------------+ | Name | Owner | Type | Created_datetime | |-------------------------------+---------+-----------------+-------------------------| | PK__Artists__25706B50FCD918B1 | dbo | primary key cns | 2019-05-02 12:56:05.853 | +-------------------------------+---------+-----------------+-------------------------+