2010-09-20 27 views
9

Planeo eliminar datos de una tabla, me gustaría saber cuántas y qué tablas tienen una referencia de clave externa a esta tabla en particular en Oracle. Como tendré que establecer las claves foráneas a nulo. Me gustaría saber la lista de todas las tablas que tienen un FK para esta tabla en particular.¿Cómo encontrar tablas con clave externa en una tabla en Oracle?

+2

posible duplicado de [Oracle todas las referencias de clave externa] (http://stackoverflow.com/questions/1171373/oracle-all-foreign-key-references) –

+0

posible duplicado de [¿Cómo puedo encontrar qué tablas hacen referencia a una tabla dada en Oracle SQL Developer?] (Http: // stackoverflow.com/questions/1143728/how-can-i-find-which-tables-reference-a-given-table-in-oracle-sql-developer) – FrustratedWithFormsDesigner

Respuesta

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

Creo que debería ser, '" Hacer referencia al nombre de restricción "', como ese es el nombre de la restricción que hace referencia a la restricción primaria, y no al revés. – jpmc26

0

No hay necesidad de hacer este paso manualmente; solo puede usar un cascading delete.

+2

Primero debe * encontrar * la tabla cuyas necesidades de FK se actualizaron para permitir la eliminación de la cassette – 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'; 

Tengo una situación en la que la tabla que me interesa no es propiedad del esquema al que me estaba conectando. Entonces necesité modificar la consulta en el currently accepted answer para usar ALL_CONSTRAINTS en vez de USER_CONSTRAINTS. En el proceso, cometí un error y encontré que la respuesta aceptada era muy difícil de leer para poder solucionarla. (La falta de explicación no ayudó). Como resultado, terminé con mi propia consulta. Es básicamente lo mismo, pero creo que es un poco más fácil de asimilar.

FK.CONSTRAINT_TYPE = 'R' filtra hacia abajo FK a un conjunto de restricciones de clave foránea, y la combinación empareja estas teclas foráneas con su "Restricción referenciada". (La restricción a la que se hace referencia suele ser la clave principal de la tabla "principal"). Finalmente, filtramos a la tabla principal que nos interesa usando SRC.OWNER = 'MY_SCHEMA' AND SRC.TABLE_NAME = 'MY_TABLE'.

Naturalmente, puede cambiar esto para usar USER_CONSTRAINTS si lo desea; simplemente elimine la verificación SRC.OWNER y los prefijos OWNER en el SELECT.

+0

FK.CONSTRAINT_TYPE = 'R' no es necesaria para este – abhihello123

+0

¿Le importaría explicar al infractor? – jpmc26

+0

@ abhihello123 Probablemente no estrictamente, ya que 'FK.R_CONSTRAINT_NAME' es probablemente' NULL' para filas con otros tipos. Por otro lado, no duele nada. – 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

Si también necesita los campos que se incluirán:

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

continuación de la consulta se dará todas las restricciones de clave externa definidas en 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

¿Por qué 'baseTable.constraint_type = 'R''? –

+1

'R' significa Integridad Referencial y queremos verificar solo la restricción de clave externa aquí. Entonces baseTable.constraint_type = 'R' debería ser usado. constraint_type también puede tomar otros valores posibles que puede verificar aquí -> https://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_1037.htm#i1576022 – nanosoft

+0

Esta consulta recogerá todas las tablas de ese nombre independientemente del esquema. Si varias tablas en diferentes esquemas tienen el mismo nombre, las seleccionará todas. Lo que es aún peor es que su elección de columnas 'SELECT'ed hace que sea imposible decir * a qué tabla se hace referencia cuando encuentra varias. – jpmc26

0

Tal vez no he entendido bien lo que pidió a Walker , pero lo que entendí es: Cómo encontrar tablas que tienen una referencia de clave externa a una tabla en particular (ej .: EMPLEADOS).

Si intento respuesta de Copa:

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 

puedo obtener las tablas en las que los empleados tengan una referencia de clave externa a.

EMPLOYEES.foreign_key => TABLES.primary_key


A continuación presentamos la actualización de SQL para recuperar las tablas que tienen una referencia de clave externa a los empleados.

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; 
Cuestiones relacionadas