Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

7 maneiras de retornar todas as tabelas com chaves estrangeiras no SQL Server


Este artigo oferece sete maneiras de retornar todas as tabelas que possuem chaves estrangeiras em um banco de dados no SQL Server.

Cada tabela é retornada apenas uma vez, independentemente de quantas chaves estrangeiras ela possa ter. Isso é diferente de retornar todas as chaves estrangeiras, juntamente com suas tabelas. Se você quiser fazer isso, consulte 11 maneiras de retornar chaves estrangeiras no SQL Server.

Todos os exemplos aqui consultam o mesmo banco de dados e, portanto, retornam o mesmo resultado.


Opção 1 – OBJECTPROPERTY() com sys.tables


A primeira opção é usar o OBJECTPROPERTY() função ao consultar o sys.tables visão do sistema.

Esta função aceita uma TableHasForeignKey argumento, que será 1 ou 0 (ou NULL ). Se for 1 , isso significa que a tabela tem uma chave estrangeira. Um valor de 0 significa que não tem nenhuma chave estrangeira. Portanto, podemos usar isso em um WHERE cláusula para retornar apenas as tabelas em que TableHasForeignKey está definido como 1 .
SELECT 
  SCHEMA_NAME(schema_id) AS [Schema], 
  name AS [Table]
FROM sys.tables
WHERE OBJECTPROPERTY(object_id, 'TableHasForeignKey') = 1
ORDER BY [Schema], [Table];

Resultado:
+----------+---------+
| Schema   | Table   |
|----------+---------|
| dbo      | Albums  |
| dbo      | Artists |
+----------+---------+

Opção 2 – OBJECTPROPERTY() com INFORMATION_SCHEMA.TABLES


Este exemplo usa OBJECTPROPERTY() ao consultar o INFORMATION_SCHEMA.TABLES visão do 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;

Resultado:
+----------------+--------------+
| TABLE_SCHEMA   | TABLE_NAME   |
|----------------+--------------|
| dbo            | Albums       |
| dbo            | Artists      |
+----------------+--------------+

Opção 3 – OBJECTPROPERTY() com sys.objects


Aqui está outra opção que usa OBJECTPROPERTY() . Desta vez eu uso ao consultar o sys.objects visão do 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]

Resultado:
+----------+---------+
| Schema   | Table   |
|----------+---------|
| dbo      | Albums  |
| dbo      | Artists |
+----------+---------+

Opção 4 – INFORMATION_SCHEMA.TABLE_CONSTRAINTS com DISTINCT


Aqui está um exemplo que consulta o INFORMATION_SCHEMA.TABLE_CONSTRAINTS visão do sistema onde o tipo de restrição é FOREIGN KEY . Nesse caso, também uso o DISTINCT cláusula para evitar que as tabelas sejam retornadas mais de uma vez quando tiverem mais de uma chave estrangeira.
SELECT DISTINCT
  CONSTRAINT_SCHEMA,
  TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';

Resultado:
+---------------------+--------------+
| CONSTRAINT_SCHEMA   | TABLE_NAME   |
|---------------------+--------------|
| dbo                 | Albums       |
| dbo                 | Artists      |
+---------------------+--------------+

Veja o que acontece se eu remover o DISTINCT cláusula:
SELECT
  CONSTRAINT_SCHEMA,
  TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY';

Resultado:
+---------------------+--------------+
| CONSTRAINT_SCHEMA   | TABLE_NAME   |
|---------------------+--------------|
| dbo                 | Albums       |
| dbo                 | Albums       |
| dbo                 | Artists      |
+---------------------+--------------+

Neste caso, os Albums table tem duas chaves estrangeiras e, portanto, recebo duas linhas para essa tabela.

Opção 5 – sys.foreign_keys com DISTINCT


Aqui está outro exemplo que usa o DISTINCT cláusula, mas desta vez estou consultando o sys.foreign_keys visão do 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];

Resultado:
+----------+---------+
| Schema   | Table   |
|----------+---------|
| dbo      | Albums  |
| dbo      | Artists |
+----------+---------+

E aqui está sem o DISTINCT cláusula:
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];

Resultado:
+----------+---------+
| Schema   | Table   |
|----------+---------|
| dbo      | Albums  |
| dbo      | Albums  |
| dbo      | Artists |
+----------+---------+

Opção 6 – sys.foreign_keys com GROUP BY


Este é semelhante ao exemplo anterior, pois consulta o sys.foreign_keys visão do sistema. A diferença é que, em vez de usar o DISTINCT cláusula, ele usa o GROUP BY cláusula em vez disso.
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);

Resultado:
+----------+---------+
| Schema   | Table   |
|----------+---------|
| dbo      | Albums  |
| dbo      | Artists |
+----------+---------+

Opção 7 – OBJECTPROPERTYEX()


Este exemplo pode estar dobrando em alguns exemplos anteriores, mas ainda vale a pena mencionar.

Qualquer um dos exemplos anteriores que usam o OBJECTPROPERTY() função, pode ser facilmente reescrito para usar o OBJECTPROPERTYEX() função. Esta função é basicamente uma extensão para OBJECTPROPERTY() , e faz tudo OBJECTPROPERTY() faz e muito mais.

Então eu poderia reescrever o primeiro exemplo nesta página com o seguinte:
SELECT 
  SCHEMA_NAME(schema_id) AS [Schema], 
  name AS [Table]
FROM sys.tables
WHERE OBJECTPROPERTYEX(object_id, 'TableHasForeignKey') = 1
ORDER BY [Schema], [Table];

Resultado:
+----------+---------+
| Schema   | Table   |
|----------+---------|
| dbo      | Albums  |
| dbo      | Artists |
+----------+---------+

Uma diferença que você deve saber é que essas duas funções retornam diferentes tipos de retorno. OBJECTPROPERTY() retorna um int enquanto OBJECTPROPERTYEX() retorna um sql_variant tipo.