【问题标题】:How to find all foreign key constraints in oracle?如何在oracle中找到所有外键约束?
【发布时间】:2020-07-06 20:29:18
【问题描述】:

在 StackOverflow 中,我可以找到关于 how to find all foreign key constraints in SQL Server 的帖子。

我只能找到关于如何在 Oralce (List of foreign keys and the tables they reference) 中查找表的所有外键约束的帖子。

我的问题是:如何列出所有表的所有外键约束,而不是 Oracle 中的表。我希望得到的答案类似于this one,但对于 Oracle。

附:我用的是oralce 11g express版。我的 oracle GUI 管理工具是 Orace SQL developer。

【问题讨论】:

    标签: oracle foreign-keys


    【解决方案1】:

    我会那样做;

    如果您希望它与同一行上的所有列聚合

    select distinct c1.owner, c1.table_name, c1.constraint_name, c2.owner, c2.table_name, 
    listagg(c2.column_name,',') WITHIN GROUP ( ORDER BY C2.POSITION) OVER ( PARTITION BY c1.owner, c1.table_name, c1.constraint_name, c2.owner, c2.table_name ) column_list
    from dba_constraints c1
    JOIN dba_cons_columns c2
    ON c1.R_CONSTRAINT_NAME=C2.CONSTRAINT_NAME and c1.r_owner=c2.owner
    where C1.constraint_type = 'R'
    

    如果你希望每列有一行,也可以这样

    select  c1.owner, c1.table_name, c1.constraint_name, c2.owner, c2.table_name, c2.column_name
    from dba_constraints c1
    JOIN dba_cons_columns c2
    ON c1.R_CONSTRAINT_NAME=C2.CONSTRAINT_NAME and c1.r_owner=c2.owner
    where C1.constraint_type = 'R'
    order by c1.owner, c1.table_name, c1.constraint_name, c2.position
    

    或者如果您想要引用列详细信息和引用列详细信息

    with constraint_colum_list as ( select owner, table_name, constraint_name, listagg(column_name,',') WITHIN GROUP ( order by position ) as column_list
                                    FROM DBA_CONS_COLUMNS GROUP BY owner, table_name, constraint_name )
    select distinct c1.owner, c1.table_name, c1.constraint_name, c2.column_list, c3.owner, c3.table_name, c3.constraint_name, c3.column_list
    from DBA_constraints c1
    JOIN constraint_colum_list c2 ON c1.CONSTRAINT_NAME=C2.CONSTRAINT_NAME and c1.owner=c2.owner
    JOIN constraint_colum_list c3 ON C1.R_CONSTRAINT_NAME=C3.CONSTRAINT_NAME AND C1.R_OWNER=C3.owner
    where C1.constraint_type = 'R' 
    -- AND c1.owner = 'YOUR_SCHEMA';
    

    【讨论】:

    • 最后一个解决方案,'AND c1.owner = 'YOUR_SCHEMA';'如果我的 oracle sql 开发者登录名是 'TestDemo',那么我需要做 'AND c1.owner = 'TestDemo';'然后我只能输出我指定/创建的外键约束。但是SQL Server不需要,只有Oracle需要这个?
    • 我的回答是基于您要求所有表上的所有外键的事实。如果您只对自己感兴趣,请将DBA_CONSTRAINTS 替换为USER_CONSTRAINTS,将DBA_CONS_COLUMNS 替换为USER_CONS_COLUMNS,您将只看到您拥有的一个
    • 太棒了。有用。我可以知道使用 DBA_CONSTRAINTS 通常用于什么其他结果吗?我只知道用户/我们指定的那些外键约束是有用的,因为我可以看到表和列之间的关系,所以我可以知道项目的业务领域。
    • 目录视图的所有工作方式都是一样的。你有一个DBA_ 版本,其中包含所有数据库的数据,ALL_ 包含调用用户可以访问的对象,USER_ 仅包含用户拥有的对象。但是其中有很多 DBS_OBJECTS DBA_TABLE DBA_TAB_PRIV 等等。所有这些都在 oracle 文档中:docs.oracle.com/cd/E11882_01/nav/catalog_views.htm
    【解决方案2】:

    此答案基于 LauDec 的解决方案。

    由于我只需要我/用户指定的所有外键约束,所以我将使用以下 SQL:

    with constraint_colum_list as ( select owner, table_name, constraint_name, listagg(column_name,',') WITHIN GROUP ( order by position ) as column_list
                                    FROM USER_CONS_COLUMNS GROUP BY owner, table_name, constraint_name )
    select distinct c1.owner, c1.table_name, c1.constraint_name, c2.column_list, c3.owner, c3.table_name, c3.constraint_name, c3.column_list
    from USER_CONSTRAINTS c1
    JOIN constraint_colum_list c2 ON c1.CONSTRAINT_NAME=C2.CONSTRAINT_NAME and c1.owner=c2.owner
    JOIN constraint_colum_list c3 ON C1.R_CONSTRAINT_NAME=C3.CONSTRAINT_NAME AND C1.R_OWNER=C3.owner
    where C1.constraint_type = 'R'; 
    

    【讨论】:

      【解决方案3】:

      不要在 where 条件中使用表名,您将获得所有表的 FK 约束。

      SELECT A.TABLE_NAME,
             A.COLUMN_NAME,
             A.CONSTRAINT_NAME, 
             C.OWNER
      FROM   ALL_CONS_COLUMNS A, 
             ALL_CONSTRAINTS C  
      WHERE  A.CONSTRAINT_NAME = C.CONSTRAINT_NAME 
      AND    C.CONSTRAINT_TYPE = 'R'
      AND    C.OWNER = 'MyDBLoginName';
      

      【讨论】:

      • 我想我需要再添加一个 where condition 'AND C.OWNER = MyDBLoginName'。否则,如果我只使用你的代码,它会列出太多列,C.OWNER 是 'SYS'、'SYSTEM'、'HR' 等,这不是我想要的。
      • 能不能也输出引用的表和引用列?
      • 我的解决方案做到了:)
      • @hemalp108 :我认为您的连接子句中缺少一个条件。约束名称不是唯一的跨模式,如果您有 2 个具有相同约束名称的模式,您将匹配不相关的行。你应该添加一个AND A.OWNER=C.OWNER
      • @LauDec 是的,你的最后一个解决方案就是我想要的。我可以知道你是如何得出这个解决方案的吗?有什么建议的参考文档,以便我可以像您一样编写解决方案吗?
      【解决方案4】:

      下面的查询给出了父表和子表的表名、列名以及每个表的约束名称。

      select a.table_name child_table, a.column_name child_column, b.table_name parent_table, b.column_name parent_column, a.position, a.constraint_name child_constraint, b.constraint_name parent_constraint
      from all_cons_columns a
      join all_constraints lc on a.owner = lc.owner and a.constraint_name = lc.constraint_name
      join all_constraints rc on lc.r_owner = rc.owner and lc.r_constraint_name = rc.constraint_name 
      join all_cons_columns b on rc.owner = b.owner and rc.constraint_name = b.constraint_name and a.position = b.position
      where a.owner = '<Schema Name>'
      and lc.constraint_type = 'R'
      order by a.constraint_name, a.table_name, a.position
      

      以下是上述 SQL 中使用的表的简要说明:

      • all_constraints - 有约束名,表名,FK 父表的约束名。此表中的 Constraint_type 字段 定义约束类型,定义外键约束 通过“R”。
      • all_cons_columns - 具有每个约束的列名列表,此表中的位置列定义了
        列在约束中。

      【讨论】:

        猜你喜欢
        • 2023-01-10
        • 1970-01-01
        • 2011-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        相关资源
        最近更新 更多