Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

7 modi per restituire tutte le tabelle con chiavi esterne in SQL Server

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.