2010-09-20 11 views
9

Ich plane, Daten aus einer Tabelle zu löschen. Ich möchte wissen, wie viele und welche Tabellen einen Fremdschlüsselbezug zu dieser bestimmten Tabelle in Oracle haben. Da muss ich die Fremdschlüssel auf null setzen. Ich möchte eine Liste aller Tabellen wissen, die einen FK zu dieser bestimmten Tabelle haben.Wie finden Tabellen mit Fremdschlüssel zu einer Tabelle in Oracle?

+2

möglich Duplikat [Oracle alle Fremdschlüssel-Referenzen] (http://stackoverflow.com/questions/1171373/oracle-all-foreign-key-references) –

+0

mögliches Duplikat von [Wie finde ich heraus, welche Tabellen in Oracle SQL Developer auf eine bestimmte Tabelle verweisen?] (Http: // stackoverflow.com/questions/1143728/how-can-i-find-which-Tabellen-Referenz-eine-gegebene-Tabelle-in-Oracle-sql-Entwickler) – FrustratedWithFormsDesigner

Antwort

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

Ich glaube, das sollte, "" Referencing Constraint Name "', als das ist der Name der Einschränkung, die auf die primäre Einschränkung verweist, nicht umgekehrt. – jpmc26

0

Sie müssen diesen Schritt nicht manuell ausführen - Sie können einfach cascading delete verwenden.

+2

Sie müssen zuerst die Tabelle finden, deren FK aktualisiert werden muss, um das Löschen von Cases zu erlauben. – 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'; 

Ich habe eine Situation, in der die Tabelle, an der ich interessiert bin, nicht dem Schema gehört, mit dem ich mich verbinde. Also musste ich die Abfrage in currently accepted answer ändern, um ALL_CONSTRAINTS statt USER_CONSTRAINTS zu verwenden. Dabei habe ich einen Fehler gemacht, und ich fand die akzeptierte Antwort sehr schwierig zu lesen, so dass ich es beheben konnte. (Der Mangel an Erklärung half nicht.) Als Ergebnis kam ich zu meiner eigenen Frage. Es ist im Grunde das Gleiche, aber ich denke, es ist ein bisschen einfacher zu grok.

FK.CONSTRAINT_TYPE = 'R' filtert FK auf einen Satz von Fremdschlüssel-Constraints nach unten, und die Paare diese Fremdschlüssel kommen mit ihren „Referenced constraint“ auf. (Die referenzierte Einschränkung ist normalerweise der Primärschlüssel der "Eltern" -Tabelle.) Schließlich filtern wir zu der Elterntabelle, an der wir interessiert sind, indem wir SRC.OWNER = 'MY_SCHEMA' AND SRC.TABLE_NAME = 'MY_TABLE' verwenden.

Natürlich können Sie dies verwenden, um USER_CONSTRAINTS zu verwenden, wenn Sie möchten; Entfernen Sie einfach die SRC.OWNER Kontrolle und die OWNER Präfixe in der SELECT.

+0

FK.CONSTRAINT_TYPE = 'R' ist dafür nicht erforderlich – abhihello123

+0

Würde sich der Downvoter darum kümmern? – jpmc26

+0

@ abhihello123 Wahrscheinlich nicht streng, da 'FK.R_CONSTRAINT_NAME' wahrscheinlich für Zeilen mit anderen Typen' NULL' ist. Auf der anderen Seite tut es nichts weh. – 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

Wenn Sie auch die Felder enthalten sein:

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

Below Abfrage alle Fremdschlüssel-Constraints auf TABLE_NAME definiert geben:

ich das falsch verstanden, was Walker fragte
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

Warum 'baseTable.constraint_type = 'R''? –

+1

'R' steht für referentielle Integrität und wir möchten hier nur die Fremdschlüsseleinschränkung überprüfen. Daher sollte baseTable.constraint_type = 'R' verwendet werden. constraint_type kann auch andere mögliche Werte annehmen, die Sie hier überprüfen können -> https://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_1037.htm#i1576022 – nanosoft

+0

Diese Abfrage wird in allen Tabellen von dieser Name unabhängig vom Schema. Wenn mehrere Tabellen in verschiedenen Schemas den gleichen Namen haben, werden sie alle ausgewählt. Was noch schlimmer ist, ist, dass Ihre Auswahl von 'SELECT'ed-Spalten es unmöglich macht zu sagen, welche * Tabelle referenziert wird, wenn sie mehrere Einsen findet. – jpmc26

0

Vielleicht , aber was ich verstanden habe, ist: Wie finde ich Tabellen, die einen Fremdschlüsselbezug zu einer bestimmten Tabelle haben (zB: EMPLOYEES).

Wenn ich Kupa Antwort versuchen:

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 

ich die Tabellen auf, welche Mitarbeiter auf einen Fremdschlüssel Bezug haben.

EMPLOYEES.foreign_key => TABLES.primary_key


unterhalb der aktualisierten SQL Siehe die Tabellen abzurufen, die einen Fremdschlüssel Bezug auf Mitarbeiter haben.

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; 
Verwandte Themen