【问题标题】:Query a Table's Foreign Key relationships查询表的外键关系
【发布时间】:2025-12-13 03:25:01
【问题描述】:

对于给定的表“foo”,我需要一个查询来生成一组具有指向 foo 的外键的表。我正在使用 Oracle 10G。

【问题讨论】:

标签: sql database oracle oracle10g


【解决方案1】:

这应该可以工作(或接近):

select table_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 here>'); 

【讨论】:

    【解决方案2】:

    下面的语句应该给孩子和他们所有的后代。我已经在 Oracle 10 数据库上对其进行了测试。

    SELECT  level, main.table_name  parent,
        link.table_name child
    FROM    user_constraints main, user_constraints link    
    WHERE   main.constraint_type    IN ('P', 'U')
    AND link.r_constraint_name  = main.constraint_name
    START WITH main.table_name  LIKE UPPER('&&table_name')
    CONNECT BY main.table_name = PRIOR link.table_name
    ORDER BY level, main.table_name, link.table_name
    

    【讨论】:

    • 很好地使用了分层检索。但是,当您有带有自引用外键的表时,它会产生错误。
    • 这是有史以来最伟大的事情。对于较新版本的 Oracle,您只需将“U”更改为“R”。
    • @focusHard,我相信在 where 子句中添加 AND main.table_name &lt;&gt; link.table_name 可以防止出现该错误。
    【解决方案3】:

    以下是如何进一步执行 Mike 的查询以从约束名称中获取 列名

    select * from user_cons_columns
    where constraint_name in (
      select 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 name here>'));
    

    【讨论】:

      【解决方案4】:

      链接到Oracle Database Online Documentation

      您可能想探索Data Dictionary views。它们有前缀:

      • 用户
      • 全部
      • 数据库管理员

      样本:

      select * from dictionary where table_name like 'ALL%' 
      

      继续 Mike 的示例,您可能希望生成脚本来启用/禁用约束。我只修改了第一行的“选择”。

      select  'alter table ' || TABLE_NAME || ' disable constraint ' || 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 here>');
      

      【讨论】:

        【解决方案5】:

        我知道现在回答有点晚了,但还是让我回答吧。上面的一些答案非常复杂,因此这里是一个更简单的答案。

        SELECT a.table_name child_table, a.column_name child_column, a.constraint_name, 
        b.table_name parent_table, b.column_name parent_column
        FROM all_cons_columns a
        JOIN all_constraints c ON a.owner = c.owner AND a.constraint_name = c.constraint_name
        join all_cons_columns b on c.owner = b.owner and c.r_constraint_name = b.constraint_name
        WHERE c.constraint_type = 'R'
        AND a.table_name = 'your table name'
        

        【讨论】:

        • 我认为这样效果更好:
           select a.table_name child_table, a.column_name child_column, a.constraint_name, b.table_name parent_table, b.column_name parent_column, a.position from user_cons_columns a join user_constraints c on a.owner = c.owner and a.constraint_name = c.constraint_name join user_cons_columns b on c.owner = b.owner and c.r_constraint_name = b.constraint_name and a.position = b.position where c.constraint_type = ' R' order by a.constraint_name, a.table_name, a.column_name, b.table_name, b.column_name
        • 当外键超过多列时,该查询返回无效结果。
        【解决方案6】:
        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;   
        

        【讨论】:

          【解决方案7】:

          下载解释数据字典表的 10G 的 Oracle 参考指南。

          上面的答案很好,但请查看可能与约束相关的其他表格。

          SELECT * FROM DICT WHERE TABLE_NAME LIKE '%CONS%';
          

          最后,获得一个像 Toad 或 SQL Developer 这样的工具,它允许您在 UI 中浏览这些内容,您需要学习使用表格,但您也应该使用 UI。

          【讨论】:

            【解决方案8】:
            select      acc.table_name, acc.constraint_name 
            from        all_cons_columns acc
            inner join all_constraints ac
                on acc.constraint_name = ac.constraint_name
            where       ac.r_constraint_name in (
                select  constraint_name
                from    all_constraints
                where   table_name='yourTable'
                );
            

            【讨论】:

              【解决方案9】:

              一张表的所有约束

              select 
              
                  uc.OWNER,
                  uc.constraint_name as TableConstraint1,
                  uc.r_constraint_name as TableConstraint2,
                  uc.constraint_type as constrainttype1,
                  us.constraint_type as constrainttype2,
                  uc.table_name as Table1,us.table_name as Table2,
                  ucc.column_name as TableColumn1, 
                  uccs.column_name as TableColumn2
              from user_constraints uc
                  left outer join user_constraints us on uc.r_constraint_name = us.constraint_name
                  left outer join USER_CONS_COLUMNS ucc on ucc.constraint_name = uc.constraint_name
                  left outer join USER_CONS_COLUMNS uccs on uccs.constraint_name = us.constraint_name
              where uc.OWNER ='xxxx' and uc.table_name='xxxx' 
              

              【讨论】:

                【解决方案10】:

                在这里加上我的两分钱。

                此查询将返回包含子列和父列的所有外键,即使在多个列上存在外键时也完美匹配:

                SELECT a.table_name child_table, a.column_name child_column, a.constraint_name, 
                b.table_name parent_table, b.column_name parent_column
                FROM all_cons_columns a
                JOIN all_constraints c ON a.owner = c.owner AND a.constraint_name = c.constraint_name
                JOIN all_cons_columns b ON c.owner = b.owner AND c.r_constraint_name = b.constraint_name AND b.position = a.position
                WHERE c.constraint_type = 'R'
                

                (受@arvinq aswer 启发)

                【讨论】: