Questo articolo offre sette modi per restituire tutte le tabelle che dispongono di chiavi esterne in un database in SQL Server.
Ogni tabella viene restituita solo una volta, indipendentemente dal numero di chiavi esterne che può avere. Questo è diverso dalla restituzione di tutte le chiavi esterne, insieme alle loro tabelle. Se vuoi farlo, vedi 11 modi per restituire chiavi esterne in SQL Server.
Tutti gli esempi qui interrogano lo stesso database e quindi restituiscono lo stesso risultato.
Opzione 1 – OBJECTPROPERTY() con sys.tables
La prima opzione consiste nell'usare OBJECTPROPERTY()
durante la query su sys.tables
vista di sistema.
Questa funzione accetta un TableHasForeignKey
argomento, che sarà 1
o 0
(o NULL
). Se è 1
, questo significa che la tabella ha una chiave esterna. Un valore di 0
significa che non ha chiavi esterne. Pertanto, possiamo usarlo in un WHERE
clausola per restituire solo quelle tabelle in cui TableHasForeignKey
è impostato su 1
.
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTY(object_id, 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table];
Risultato:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Opzione 2 – OBJECTPROPERTY() con INFORMATION_SCHEMA.TABLES
Questo esempio utilizza OBJECTPROPERTY()
durante la query su INFORMATION_SCHEMA.TABLES
vista di sistema.
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE OBJECTPROPERTY(OBJECT_ID(CONCAT(TABLE_SCHEMA, '.', TABLE_NAME)),'TableHasForeignKey') = 1 AND TABLE_TYPE='BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME;
Risultato:
+----------------+--------------+ | TABLE_SCHEMA | TABLE_NAME | |----------------+--------------| | dbo | Albums | | dbo | Artists | +----------------+--------------+
Opzione 3 – OBJECTPROPERTY() con sys.objects
Ecco ancora un'altra opzione che utilizza OBJECTPROPERTY()
. Questa volta lo uso per interrogare sys.objects
vista di sistema.
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.objects WHERE type = 'U' AND OBJECTPROPERTY(OBJECT_ID(CONCAT(SCHEMA_NAME(schema_id), '.', name)), 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table]
Risultato:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Opzione 4 – INFORMATION_SCHEMA.TABLE_CONSTRAINTS con DISTINCT
Ecco un esempio che interroga INFORMATION_SCHEMA.TABLE_CONSTRAINTS
vista di sistema in cui il tipo di vincolo è FOREIGN KEY
. In questo caso, utilizzo anche il DISTINCT
clausola per evitare che le tabelle vengano restituite più di una volta quando hanno più di una chiave esterna.
SELECT DISTINCT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
Risultato:
+---------------------+--------------+ | CONSTRAINT_SCHEMA | TABLE_NAME | |---------------------+--------------| | dbo | Albums | | dbo | Artists | +---------------------+--------------+
Ecco cosa succede se rimuovo il DISTINCT
clausola:
SELECT CONSTRAINT_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';
Risultato:
+---------------------+--------------+ | CONSTRAINT_SCHEMA | TABLE_NAME | |---------------------+--------------| | dbo | Albums | | dbo | Albums | | dbo | Artists | +---------------------+--------------+
In questo caso gli Albums
table ha due chiavi esterne, quindi ottengo due righe per quella tabella.
Opzione 5 – sys.foreign_keys con DISTINCT
Ecco un altro esempio che utilizza DISTINCT
clausola, ma questa volta sto interrogando il sys.foreign_keys
vista di sistema.
SELECT DISTINCT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk ORDER BY [Schema], [Table];
Risultato:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Ed eccolo qui senza il DISTINCT
clausola:
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk ORDER BY [Schema], [Table];
Risultato:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Albums | | dbo | Artists | +----------+---------+
Opzione 6 – sys.foreign_keys con GROUP BY
Questo è simile all'esempio precedente in quanto interroga sys.foreign_keys
vista del sistema. La differenza è che, invece di usare il DISTINCT
clausola, utilizza il GROUP BY
clausola invece.
SELECT OBJECT_SCHEMA_NAME(fk.parent_object_id) AS [Schema], OBJECT_NAME(fk.parent_object_id) AS [Table] FROM sys.foreign_keys AS fk GROUP BY OBJECT_SCHEMA_NAME(fk.parent_object_id), OBJECT_NAME(fk.parent_object_id);
Risultato:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Opzione 7 – OBJECTPROPERTYEX()
Questo esempio potrebbe raddoppiare rispetto ad alcuni esempi precedenti, ma vale comunque la pena menzionarlo.
Qualsiasi degli esempi precedenti che utilizzano OBJECTPROPERTY()
funzione, potrebbe essere facilmente riscritto per utilizzare OBJECTPROPERTYEX()
funzione. Questa funzione è fondamentalmente un'estensione di OBJECTPROPERTY()
, e fa tutto OBJECTPROPERTY()
fa e altro.
Quindi potrei riscrivere il primo esempio in questa pagina con quanto segue:
SELECT SCHEMA_NAME(schema_id) AS [Schema], name AS [Table] FROM sys.tables WHERE OBJECTPROPERTYEX(object_id, 'TableHasForeignKey') = 1 ORDER BY [Schema], [Table];
Risultato:
+----------+---------+ | Schema | Table | |----------+---------| | dbo | Albums | | dbo | Artists | +----------+---------+
Una differenza che dovresti sapere è che queste due funzioni restituiscono diversi tipi di ritorno. OBJECTPROPERTY()
restituisce un int mentre OBJECTPROPERTYEX()
restituisce una variante_sql digitare.