Eu quero uma maneira de estabelecer quais colunas em um determinado banco de dados são unidas por meio de relacionamentos PK/FK. Eu posso retornar as informações PK/FK para uma determinada tabela via
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS cu
WHERE EXISTS (
SELECT tc.*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
WHERE tc.CONSTRAINT_CATALOG = 'MyDatabase'
AND tc.TABLE_NAME = 'MyTable'
/*AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY'*/
AND tc.CONSTRAINT_NAME = cu.CONSTRAINT_NAME);
GO
mas para um PK retornado de tal consulta, como faço para estabelecer o FK associado (supondo que haja um)?
Eu sei que você também pode obter as tabelas referenciadas via:
SELECT CONSTRAINT_NAME = name,
FOREIGN_SCHEMA = OBJECT_SCHEMA_NAME(parent_object_id),
FOREIGN_TABLE = OBJECT_NAME(parent_object_id),
REFERENCED_SCHEMA = OBJECT_SCHEMA_NAME(referenced_object_id),
REFERENCED_TABLE = OBJECT_NAME(referenced_object_id)
FROM sys.foreign_keys
WHERE OBJECT_NAME(referenced_object_id) = 'MyTable';
GO
mas estou lutando agora para obter as referências de coluna explícitas.
Estou criando um gerador de script para o QlikView. Para gerar o script, preciso das restrições e dos links associados. Eu preciso de todas as informações de restrição para qualquer coluna (se houver).
Eu quero construir uma classe de banco de dados que contenha todas as informações de um determinado banco de dados. Essa estrutura de classe database.table.column.constraints
será usada para obter as correspondências entre diferentes colunas em PK/FKs.
Claramente algumas colunas terão apenas FKs e neste caso eu também quero recuperar as informações de PK da chave correspondente; alguns terão apenas PKs e aí eu quero o inverso. Alguns, claro, podem ter ambos.
Aqui está uma consulta simples para corresponder as chaves estrangeiras às tabelas/colunas referenciadas:
A saída tem oito colunas: os nomes de tabela e coluna para as chaves estrangeiras (FK_table, FK_column), os nomes das restrições de chave estrangeira (FK_name), o PK referenciado ou a tabela de índice exclusivo e os nomes das colunas (PK_table, PK_column), o nome do PK referenciado ou índice exclusivo (PK_name) e as ações em cascata de atualização/exclusão (Delete_Action, Update_Action).
(Editado para adicionar mais colunas de saída.)
EDIT: Estou de volta 6 anos depois com uma versão melhorada disso. Percebi que a consulta original realmente não lida bem com chaves estrangeiras de várias colunas e também queria poder identificar rapidamente chaves estrangeiras desabilitadas, não confiáveis ou não indexadas. Então aqui está a nova versão que corrige tudo isso.
As chaves de várias colunas são mostradas como listas separadas por vírgulas em
FK_columns
ePK_columns
, usando o tradicionalFOR XML
/STUFF
abuse. AFK_indexes
coluna mostra os nomes de quaisquer índices na tabela de chave estrangeira que poderiam ser usados para satisfazer buscas usando as colunas de chave estrangeira (principalmente para otimizar exclusões ou atualizações na tabela de chave primária). Se forNULL
, então você tem uma chave estrangeira não indexada. Você pode ajustar oORDER BY
, ou adicionar umaWHERE
cláusula (comentada abaixo) se quiser classificar pelo nome da tabela PK, filtrar por tabelas PK/FK específicas, etc.Essa consulta conecta todos os relacionamentos FK no banco de dados - nome da restrição FK, esquema/tabela da tabela de referência, nome da coluna de referência, esquema/tabela da tabela referenciada e nome da coluna referenciada. Haverá várias linhas para uma restrição de várias colunas.
Se você estiver atrás das colunas de uma restrição de chave primária específica e já souber o nome dessa restrição PK, poderá escrever isto:
Se você quiser apenas incluir o nome do PK junto com as outras informações:
Também existem truques para obter a lista de colunas em, digamos, uma lista separada por vírgulas ou colunas individuais, em vez de se espalhar pelas linhas, mas não vou investir na modificação dessas consultas para produzir isso até saber exatamente qual formulário você está atrás.