【问题标题】:How to find tables having foreign key to a table in Oracle?如何在Oracle中查找具有表外键的表?
【发布时间】:2010-09-20 13:31:31
【问题描述】:

我打算从一个表中删除数据,我想知道在 Oracle 中有多少表以及哪些表具有对这个特定表的外键引用。因为我必须将外键设置为空。我想知道对这个特定表有 FK 的所有表的列表。

【问题讨论】:

标签: oracle key


【解决方案1】:
SELECT
  FK.OWNER||'.'||FK.TABLE_NAME AS CHILD_TABLE,
  SRC.OWNER||'.'||SRC.TABLE_NAME AS PARENT_TABLE,
  FK.CONSTRAINT_NAME AS FK_CONSTRAINT,
  SRC.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT
FROM ALL_CONSTRAINTS FK
JOIN ALL_CONSTRAINTS SRC ON FK.R_CONSTRAINT_NAME = SRC.CONSTRAINT_NAME
WHERE
  FK.CONSTRAINT_TYPE = 'R'
  AND SRC.OWNER = 'MY_SCHEMA'
  AND SRC.TABLE_NAME = 'MY_TABLE';

我有一种情况,我感兴趣的表不属于我连接的架构。所以我需要修改currently accepted answer 中的查询以使用ALL_CONSTRAINTS 而不是USER_CONSTRAINTS。在这个过程中,我犯了一个错误,我发现接受的答案很难阅读,所以我可以修复它。 (缺乏解释并没有帮助。)结果,我最终提出了自己的查询。基本是一样的,不过我觉得摸起来容易一点。

FK.CONSTRAINT_TYPE = 'R'FK 过滤到一组外键约束,并且连接将这些外键与其“引用约束”配对。 (引用的约束通常是“父”表的主键。)最后,我们使用SRC.OWNER = 'MY_SCHEMA' AND SRC.TABLE_NAME = 'MY_TABLE' 过滤到我们感兴趣的父表。

当然,如果您愿意,您可以将其切换为使用USER_CONSTRAINTS;只需删除SRC.OWNER 检查和SELECT 中的OWNER 前缀即可。

【讨论】:

  • FK.CONSTRAINT_TYPE = 'R' 不是必需的
  • @abhihello123 可能并不严格,因为 FK.R_CONSTRAINT_NAME 对于其他类型的行可能是 NULL。另一方面,它不会伤害任何东西。
【解决方案2】:
SELECT d.table_name,

       d.constraint_name "Primary Constraint Name",

       b.constraint_name "Referenced Constraint Name"

FROM user_constraints d,

     (SELECT c.constraint_name,

             c.r_constraint_name,

             c.table_name

      FROM user_constraints c 

      WHERE table_name='EMPLOYEES' --your table name instead of EMPLOYEES

      AND constraint_type='R') b

WHERE d.constraint_name=b.r_constraint_name

【讨论】:

  • 我认为应该是"Referencing Constraint Name",因为这是引用主要约束的约束的名称,而不是相反。
【解决方案3】:

以下查询将给出在 TABLE_NAME 上定义的所有外键约束:

select baseTable.* from all_constraints baseTable , all_constraints referentedTable 
    where baseTable.R_CONSTRAINT_NAME = referentedTable.CONSTRAINT_NAME
    and baseTable.constraint_type = 'R'
    and referentedTable.table_name = 'TABLE_NAME';

【讨论】:

  • 为什么是baseTable.constraint_type = 'R'
  • 'R' 代表参照完整性,我们只想在这里检查外键约束。所以应该使用 baseTable.constraint_type = 'R'。 constraint_type 还可以采用其他可能的值,您可以在此处查看 -> docs.oracle.com/cd/B19306_01/server.102/b14237/…
  • 此查询将选择该名称的所有表,而不管架构如何。如果不同模式中的多个表具有相同的名称,它将选择所有表。更糟糕的是,您对SELECTed 列的选择使得当它确实找到多个表时无法分辨出 哪个 表被引用。
  • @jpmc26 :在这种情况下,您可以在模式上添加一个过滤子句,就是这样。必须根据他们的自定义需求定制查询,很简单。
  • @nanosoft 除非您添加了过滤器,否则它将 1. 表现得像实际预期的那样,并且 2. 与现有答案相同。 “你可以自己解决它”并不是为它的行为无益的方式辩护。
【解决方案4】:

也许我误解了 Walker 的要求,但我的理解是:如何找到具有对特定表的外键引用的表(例如:EMPLOYEES)。

如果我尝试 Kupa 的回答:

select d.table_name,
       d.constraint_name "Primary Constraint Name",
       b.constraint_name "Referenced Constraint Name"

from user_constraints d,

     (select c.constraint_name,
             c.r_constraint_name,
             c.table_name
      from user_constraints c 
      where table_name='EMPLOYEES' --your table name instead of EMPLOYEES
      and constraint_type='R') b

where d.constraint_name=b.r_constraint_name

我得到了 EMPLOYEES 有外键引用的表。

EMPLOYEES.foreign_key => TABLES.primary_key


请参阅下面更新的 sql 以检索具有对 EMPLOYEES 的外键引用的表。

TABLES.foreign_key => EMPLOYEES.primary_key

select b.table_name "Table Name",
   b.constraint_name "Constraint Name",
   d.table_name "Referenced Table Name",
   d.constraint_name "Referenced Constraint Name"

from user_constraints d,

 (select c.constraint_name,
         c.r_constraint_name,
         c.table_name
  from user_constraints c
  where constraint_type='R') b

where d.table_name = 'EMPLOYEES' --your table name instead of EMPLOYEES
and b.r_constraint_name = d.constraint_name;

【讨论】:

    【解决方案5】:

    如果您还需要包含这些字段:

    select b.table_name      "Referencing Table", 
           b.CONSTRAINT_NAME "Referencing Constraint",
           (select wm_concat(column_name)
              from all_cons_columns
             where owner = b.owner
               and constraint_name = b.CONSTRAINT_NAME
           ) "Referencing Columns",
           a.CONSTRAINT_NAME         "Referenced Constraint",
           (select wm_concat(column_name)
              from all_cons_columns
             where owner = a.owner
               and constraint_name = a.CONSTRAINT_NAME
           ) "Referenced columns"
      from all_constraints a,
           all_constraints b
     where a.owner = b.r_owner
       and a.owner = '<<OWNER>>'
       and a.table_name = '<<TABLE_NAME>>'
       and a.constraint_type in ('P', 'U')
       and b.constraint_type = 'R'
       and b.R_CONSTRAINT_NAME = a.constraint_name
    

    【讨论】:

    • wm_concat 在我的 Oracle 版本中不起作用。我将这两行替换为: select listagg(column_name) within group (order by position) "columns"
    【解决方案6】:

    无需手动执行此步骤 - 您只需使用 cascading delete

    【讨论】:

    • 您需要先找到需要更新 FK 以允许删除大小写的表
    【解决方案7】:
    SELECT a.table_name, a.column_name, a.constraint_name, c.owner, 
           -- referenced pk
           c.r_owner, c_pk.table_name r_table_name, c_pk.constraint_name r_pk
      FROM all_cons_columns a
      JOIN all_constraints c ON a.owner = c.owner
                            AND a.constraint_name = c.constraint_name
      JOIN all_constraints c_pk ON c.r_owner = c_pk.owner
                               AND c.r_constraint_name = c_pk.constraint_name
     WHERE c.constraint_type = 'R'
       AND a.table_name = :TableName
    

    【讨论】:

      【解决方案8】:
      SELECT CONSTRAINT_NAME from ALL_CONSTRAINTS WHERE OWNER= sys_context('userenv','current_schema') AND CONSTRAINT_TYPE='R';
      

      【讨论】:

        猜你喜欢
        • 2015-11-04
        • 1970-01-01
        • 2021-12-08
        • 1970-01-01
        • 2013-05-15
        • 2017-05-15
        • 2010-10-22
        • 1970-01-01
        相关资源
        最近更新 更多