2010-09-20 3 views
9

Я планирую удалить данные из таблицы, я хотел бы знать, сколько и какие таблицы имеют ссылку на внешний ключ для этой конкретной таблицы в Oracle. Поскольку мне придется установить внешние ключи в значение null. Я хотел бы знать список всех таблиц, которые имеют FK для этой конкретной таблицы.Как найти таблицы, имеющие внешний ключ для таблицы в Oracle?

+2

возможно дубликат [Oracle все ссылки на внешние ключи] (http://stackoverflow.com/questions/1171373/oracle-all-foreign-key-references) –

+0

Возможный дубликат [Как узнать, какие таблицы ссылаются на данную таблицу в Oracle SQL Developer?] (Http: // stackoverflow.com/questions/1143728/how-can-i-find-which-tables-reference-a-given-table-in-oracle-sql-developer) – FrustratedWithFormsDesigner

ответ

12
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 
+2

Я считаю, что это должно быть '' Ссылка на ограничение имени '', as это имя ограничения, которое ссылается на основное ограничение, а не наоборот. – jpmc26

0

Нет необходимости делать этот шаг вручную - вы можете просто использовать cascading delete.

+2

Вам нужно сначала * найти * таблицу, FK которой необходимо обновить, чтобы разрешить каскадное удаление, хотя – Brian

8
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 на набор ограничений внешнего ключа, а соединения соединяют эти внешние ключи с их «ссылочным ограничением». (Связанное ограничение обычно является первичным ключом таблицы «parent».) Наконец, мы фильтруем до родительской таблицы, которую мы заинтересованы в использовании SRC.OWNER = 'MY_SCHEMA' AND SRC.TABLE_NAME = 'MY_TABLE'.

Естественно, вы можете переключить его, чтобы использовать USER_CONSTRAINTS, если хотите; просто удалите отметку SRC.OWNER и префиксы OWNER в SELECT.

+0

FK.CONSTRAINT_TYPE = 'R' не требуется для этого – abhihello123

+0

Может ли нижестоящий помочь объяснить? – jpmc26

+0

@ abhihello123 Вероятно, не строго, поскольку 'FK.R_CONSTRAINT_NAME', вероятно,' NULL' для строк с другими типами. С другой стороны, это ничего не болит. – jpmc26

0
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 
1

Если необходимо также поля, которые будут включены:

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 
6

Ниже запроса даст все ограничения внешнего ключа, определенные на 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'; 
+0

Почему 'baseTable.constraint_type = 'R''? –

+1

«R» означает ссылочную целостность, и мы хотим проверить только ограничение внешнего ключа здесь. Поэтому следует использовать baseTable.constraint_type = 'R'. constraint_type также может принимать другие возможные значения, которые вы можете проверить здесь -> https://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_1037.htm#i1576022 – nanosoft

+0

Этот запрос будет отображаться на всех таблицах это имя независимо от схемы. Если несколько таблиц в разных схемах имеют одинаковое имя, они будут выбирать все из них. Еще хуже то, что ваш выбор столбцов «SELECT» не позволяет указать, на какую * таблицу ссылаются, когда он находит несколько. – jpmc26

0

Может быть, я неправильно понял, что спросил Уокер , но я понял: как найти таблицы, которые имеют ссылку на внешний ключ для конкретной таблицы (например: СОТРУДНИКИ).

Если я пытаюсь ответить Купа в:

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.foreign_key => TABLES.primary_key


Смотрите ниже обновленный SQL для извлечения таблиц, которые имеют внешний ключ ссылку на СОТРУДНИК.

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; 
Смежные вопросы