Como posso encontrar quais tabelas referenciam uma determinada tabela no Oracle SQL Developer?

199

No Oracle SQL Developer , se estou visualizando as informações em uma tabela, posso ver as restrições, o que me permite ver as chaves estrangeiras (e, portanto, quais tabelas são referenciadas por esta tabela) e posso ver as dependências para ver o que pacotes e tais referências à tabela. Mas não sei como encontrar quais tabelas referenciam a tabela.

Por exemplo, digamos que estou olhando para a empmesa. Há outra tabela emp_deptque captura quais funcionários trabalham em quais departamentos, que referenciam a emptabela emp_id, a chave primária da emptabela. Existe uma maneira (através de algum elemento da interface do usuário no programa, não através do SQL) para descobrir que a emp_depttabela faz referência à emptabela, sem que eu precise saber que a emp_depttabela existe?

Rudd Zwolinski
fonte

Respostas:

258

Não. Não existe essa opção disponível no Oracle SQL Developer.

É necessário executar uma consulta manualmente ou usar outra ferramenta (por exemplo, o PLSQL Developer possui essa opção). O SQL a seguir é aquele usado pelo PLSQL Developer:

select table_name, constraint_name, status, owner
from all_constraints
where r_owner = :r_owner
and constraint_type = 'R'
and r_constraint_name in
 (
   select constraint_name from all_constraints
   where constraint_type in ('P', 'U')
   and table_name = :r_table_name
   and owner = :r_owner
 )
order by table_name, constraint_name

Onde r_ownerestá o esquema e r_table_namea tabela para a qual você está procurando referências. Os nomes diferenciam maiúsculas de minúsculas


Cuidado, pois na guia relatórios do Oracle SQL Developer existe a opção "Todas as tabelas / dependências", de ALL_DEPENDENCIES, que se refere a " dependências entre procedimentos, pacotes, funções, corpos de pacotes e gatilhos acessíveis ao usuário atual, incluindo dependências nas visualizações criadas sem nenhum link de banco de dados ". . Então, este relatório não tem valor para sua pergunta.

FerranB
fonte
30
Obrigado pela resposta. Que vergonha para o Oracle Sql Developer por sugar.
Greg
1
Você mencionou que o PLSQL Developer pode executar esta função, pode explicar como?
Nicholas
4
@Nicholas, No navegador de objetos, selecione uma tabela, clique com o botão direito do mouse em uma tabela e selecione "Referências a Chaves Estrangeiras"
FerranB
3
Esta resposta referencia que o SQL Developer 4.1 e superior agora têm uma opção na guia "Modelo" que mostrará essas informações no formato ERD.
precisa saber é o seguinte
1
r_owner é o esquema que você está usando, r_table_name é a tabela que você está procurando referências
Flowy
108

Para adicionar isso ao SQL Developer como uma extensão, faça o seguinte:

  1. Salve o código abaixo em um arquivo xml (por exemplo, fk_ref.xml):
<items>
    <item type="editor" node="TableNode" vertical="true">
    <title><![CDATA[FK References]]></title>
    <query>
        <sql>
            <![CDATA[select a.owner,
                            a.table_name,
                            a.constraint_name,
                            a.status
                     from   all_constraints a
                     where  a.constraint_type = 'R'
                            and exists(
                               select 1
                               from   all_constraints
                               where  constraint_name=a.r_constraint_name
                                      and constraint_type in ('P', 'U')
                                      and table_name = :OBJECT_NAME
                                      and owner = :OBJECT_OWNER)
                               order by table_name, constraint_name]]>
        </sql>
    </query>
    </item>
</items>
  1. Adicione a extensão ao SQL Developer:

    • Ferramentas> Preferências
    • Banco de Dados> Extensões Definidas pelo Usuário
    • Clique no botão "Adicionar linha"
    • No tipo, escolha "EDITOR", o local é onde você salvou o arquivo xml acima
    • Clique em "Ok" e reinicie o SQL Developer
  2. Navegue para qualquer tabela e agora você verá uma guia adicional ao lado da SQL one, denominada FK References, que exibe as novas informações de FK.

  3. Referência

junaling
fonte
Você sabe qual é o nome do nó para Pacotes? Todos os links xsd que encontro na Web não são mais válidos (como no Oracle os removemos).
James Sumners
1
Eu adicionei uma pequena alteração para a sua sugestão: e proprietário = usuário antes do fim por, de modo que se você tiver duas instâncias das mesmas tabelas em dois esquemas que você começa apenas as referências relevantes para o seu esquema
user1708042
Eu adicionei esta condição: and owner = :OBJECT_OWNERantes and exists.
Denis
3
@ M-Denis, nesse caso, você pode perder referências de outros esquemas.
usar o seguinte código
depois de aplicar isso e executar describe books;e select * from books;, ele não mostra a guia fk reference na Oracle sql developer VM.
mLstudent33 22/02
36

Substitua [Your TABLE] por emp na consulta abaixo

select owner,constraint_name,constraint_type,table_name,r_owner,r_constraint_name
  from all_constraints 
 where constraint_type='R'
   and r_constraint_name in (select constraint_name 
                               from all_constraints 
                              where constraint_type in ('P','U') 
                                and table_name='[YOUR TABLE]');
Lexu
fonte
Eu acho que constraint_type in ('P','U') é supérfluo, porque se o tipo de restrição TOTO de uma restrição é 'R', então r_constraint_name do TOTO é, obviamente, o nome de uma restrição do tipo 'P' OU 'U' na tabela referenciada. Não há necessidade de especificá-lo. Você está usando um IN, então é como muitos ORe nós apenas nos preocupamos com o único operando de OR que é avaliado como verdadeiro.
29416 Gab
10

Você pode consultar isso na ALL_CONSTRAINTSexibição:

SELECT table_name
FROM ALL_CONSTRAINTS
WHERE constraint_type = 'R' -- "Referential integrity"
  AND r_constraint_name IN
    ( SELECT constraint_name
      FROM ALL_CONSTRAINTS
      WHERE table_name = 'EMP'
        AND constraint_type IN ('U', 'P') -- "Unique" or "Primary key"
    );
Adam Paynter
fonte
1
Chaves estrangeiras podem referenciar Chaves Exclusivas, não apenas chaves primárias; também, o nome da tabela pode ser usado em vários esquemas, o que resultaria em várias correspondências. Você também precisa usar a coluna 'Proprietário' se usar 'All_Constraints' e não 'User_Constraints'.
58630 Mark Roddy
Obrigado por comentar o 'R' 'U' e 'P' são
Jeff
Não esqueça o ponto-e-vírgula no final da solicitação SQL.
29516 Gab
A propósito, o tipo de restrição em ('P', 'U') é supérfluo, porque se o tipo de restrição de uma restrição TOTO for 'R', então r_constraint_name do TOTO será, obviamente, o nome de uma restrição do tipo 'P' OR 'U 'na tabela referenciada. Não há necessidade de especificá-lo.
29416 Gab
9

O SQL Developer 4.1, lançado em maio de 2015, adicionou uma guia Modelo que mostra as chaves estrangeiras da tabela que se referem à sua tabela em um formato de Diagrama de relacionamento com entidades.

Mark A. Fitzgerald
fonte
1
Menos útil se você precisar disso em um script por algum motivo, mas se precisar conhecer apenas as conexões, isso parece ser o caminho moderno a seguir.
precisa saber é o seguinte
1
@SnoringFrog bem tecnicamente a questão pede um elemento de interface de modo que este é a resposta mais adequada
WhatsThePoint
4

Que tal algo como isso:

SELECT c.constraint_name, c.constraint_type, c2.constraint_name, c2.constraint_type, c2.table_name
  FROM dba_constraints c JOIN dba_constraints c2 ON (c.r_constraint_name = c2.constraint_name)
 WHERE c.table_name = <TABLE_OF_INTEREST>
   AND c.constraint_TYPE = 'R';
DCookie
fonte
2
Isso funcionou para mim quando mudei o nome da tabela de dba_constraintspara all_constraintsassim:SELECT c.constraint_name, c.constraint_type, c2.constraint_name, c2.constraint_type, c2.table_name FROM all_constraints c JOIN all_constraints c2 ON (c.r_constraint_name = c2.constraint_name) WHERE c.table_name = '<TABLE_OF_INTEREST>' AND c.constraint_TYPE = 'R';
chrisjleu 15/10/12
4
SELECT DISTINCT table_name, 
                constraint_name, 
                column_name, 
                r_table_name, 
                position, 
                constraint_type 
FROM   (SELECT uc.table_name, 
               uc.constraint_name, 
               cols.column_name, 
               (SELECT table_name 
                FROM   user_constraints 
                WHERE  constraint_name = uc.r_constraint_name) r_table_name, 
               (SELECT column_name 
                FROM   user_cons_columns 
                WHERE  constraint_name = uc.r_constraint_name 
                       AND position = cols.position)           r_column_name, 
               cols.position, 
               uc.constraint_type 
        FROM   user_constraints uc 
               inner join user_cons_columns cols 
                       ON uc.constraint_name = cols.constraint_name 
        WHERE  constraint_type != 'C') 
START WITH table_name = '&&tableName' 
           AND column_name = '&&columnName' 
CONNECT BY NOCYCLE PRIOR table_name = r_table_name 
                         AND PRIOR column_name = r_column_name; 
Abu Turab
fonte
Isso é extremamente útil - mostra recursivamente todas as tabelas de uma determinada tabela raiz, que mantêm como chave o valor de uma coluna que você seleciona nessa tabela raiz. Soberbo, obrigado.
Ev0oD
Isso é muito legal - bom trabalho. Gostaria apenas de adicionar lower () para comparar table_name e column_name.
Tobias Otto
4

Ele está no produto há anos - embora não estivesse no produto em 2011.

Mas, basta clicar na página Modelo.

Verifique se você possui pelo menos a versão 4.0 (lançada em 2013) para acessar esse recurso.

insira a descrição da imagem aqui

thatjeffsmith
fonte
0

Para adicionar à resposta acima para o plugin sql developer, usar o xml abaixo ajudará a obter a coluna associada à chave estrangeira.

    <items>
        <item type="editor" node="TableNode" vertical="true">
        <title><![CDATA[FK References]]></title>
        <query>
            <sql>
                <![CDATA[select a.owner,
                                a.constraint_name,
                                a.table_name,
                                b.column_name,
                                a.status
                         from   all_constraints a
                         join   all_cons_columns b ON b.constraint_name = a.constraint_name
                         where  a.constraint_type = 'R'
                                and exists(
                                   select 1
                                   from   all_constraints
                                   where  constraint_name=a.r_constraint_name
                                          and constraint_type in ('P', 'U')
                                          and table_name = :OBJECT_NAME
                                          and owner = :OBJECT_OWNER)
                                   order by table_name, constraint_name]]>
            </sql>
        </query>
        </item>
    </items>
Srinivasa Raghavan R
fonte