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.