Liste der ausländischen Schlüssel und der Tabellen, auf die sie sich verweisen
-
20-09-2019 - |
Frage
Ich versuche eine Abfrage zu finden, die mir eine Liste der Fremdschlüssel für eine Tabelle und die Tabellen und Spalten zurückgeben, auf die sie sich verweisen. Ich bin auf halbem Weg mit
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 a.table_name=:TableName
and C.CONSTRAINT_TYPE = 'R'
Aber ich muss noch wissen, auf welcher Tabelle und der Primärschlüssel dieser Schlüssel verwiesen wird. Wie würde ich das bekommen?
Lösung
Der referenzierte Primärschlüssel wird in den Spalten beschrieben r_owner
und r_constraint_name
des Tisches ALL_CONSTRAINTS
. Dadurch erhalten Sie die Informationen, die Sie möchten:
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
Andere Tipps
Versuche dies:
select * from all_constraints where r_constraint_name in (select constraint_name
from all_constraints where table_name='YOUR_TABLE_NAME');
Hier ist ein Allzweckskript, das wir verwenden, das unglaublich praktisch war.
Speichern Sie es, damit Sie es direkt ausführen können (@fkeys.sql). Sie können nach dem Eigentümer und entweder über die Eltern- oder Kindertabelle suchen und ausländische Schlüsselbeziehungen anzeigen. Das aktuelle Skript spricht ausdrücklich auf C: sqlrpts, sodass Sie diesen Ordner der Änderung dieser Zeile zu etwas erstellen müssen, das Sie verwenden möchten.
REM ########################################################################
REM ##
REM ## fkeys.sql
REM ##
REM ## Displays the foreign key relationships
REM ##
REM #######################################################################
CLEAR BREAK
CLEAR COL
SET LINES 200
SET PAGES 54
SET NEWPAGE 0
SET WRAP OFF
SET VERIFY OFF
SET FEEDBACK OFF
break on table_name skip 2 on constraint_name on r_table_name skip 1
column CHILDCOL format a60 head 'CHILD COLUMN'
column PARENTCOL format a60 head 'PARENT COLUMN'
column constraint_name format a30 head 'FK CONSTRAINT NAME'
column delete_rule format a15
column bt noprint
column bo noprint
TTITLE LEFT _DATE CENTER 'FOREIGN KEY RELATIONSHIPS ON &new_prompt' RIGHT 'PAGE:'FORMAT 999 SQL.PNO SKIP 2
SPOOL C:\SQLRPTS\FKeys_&new_prompt
ACCEPT OWNER_NAME PROMPT 'Enter Table Owner (or blank for all): '
ACCEPT PARENT_TABLE_NAME PROMPT 'Enter Parent Table or leave blank for all: '
ACCEPT CHILD_TABLE_NAME PROMPT 'Enter Child Table or leave blank for all: '
select b.owner || '.' || b.table_name || '.' || b.column_name CHILDCOL,
b.position,
c.owner || '.' || c.table_name || '.' || c.column_name PARENTCOL,
a.constraint_name,
a.delete_rule,
b.table_name bt,
b.owner bo
from all_cons_columns b,
all_cons_columns c,
all_constraints a
where b.constraint_name = a.constraint_name
and a.owner = b.owner
and b.position = c.position
and c.constraint_name = a.r_constraint_name
and c.owner = a.r_owner
and a.constraint_type = 'R'
and c.owner like case when upper('&OWNER_NAME') is null then '%'
else upper('&OWNER_NAME') end
and c.table_name like case when upper('&PARENT_TABLE_NAME') is null then '%'
else upper('&PARENT_TABLE_NAME') end
and b.table_name like case when upper('&CHILD_TABLE_NAME') is null then '%'
else upper('&CHILD_TABLE_NAME') end
order by 7,6,4,2
/
SPOOL OFF
TTITLE OFF
SET FEEDBACK ON
SET VERIFY ON
CLEAR BREAK
CLEAR COL
SET PAGES 24
SET LINES 100
SET NEWPAGE 1
UNDEF OWNER
Dadurch wird die Hierarchie fremder Schlüssel für eine bestimmte Tabelle und Spalte und Spalten von Kind und Enkelkind und allen Nachkommentischen zurückgegeben. Es verwendet Sub-Querien, um user_constraints r_table_name und r_column_name hinzuzufügen und dann Zeilen zu verbinden.
select distinct table_name, constraint_name, column_name, r_table_name, position, constraint_type
from (
SELECT uc.table_name,
uc.constraint_name,
cols.column_name,
(select table_name from user_constraints where constraint_name = uc.r_constraint_name)
r_table_name,
(select column_name from user_cons_columns where constraint_name = uc.r_constraint_name and position = cols.position)
r_column_name,
cols.position,
uc.constraint_type
FROM user_constraints uc
inner join user_cons_columns cols on uc.constraint_name = cols.constraint_name
where constraint_type != 'C'
)
start with table_name = 'MY_TABLE_NAME' and column_name = 'MY_COLUMN_NAME'
connect by nocycle
prior table_name = r_table_name
and prior column_name = r_column_name;
Hier ist eine andere Lösung. Die Standardansichten von SYS sind so langsam (ca. 10s in meiner Situation). Dies ist viel schneller als das (ca. 0,5s).
SELECT
CONST.NAME AS CONSTRAINT_NAME,
RCONST.NAME AS REF_CONSTRAINT_NAME,
OBJ.NAME AS TABLE_NAME,
COALESCE(ACOL.NAME, COL.NAME) AS COLUMN_NAME,
CCOL.POS# AS POSITION,
ROBJ.NAME AS REF_TABLE_NAME,
COALESCE(RACOL.NAME, RCOL.NAME) AS REF_COLUMN_NAME,
RCCOL.POS# AS REF_POSITION
FROM SYS.CON$ CONST
INNER JOIN SYS.CDEF$ CDEF ON CDEF.CON# = CONST.CON#
INNER JOIN SYS.CCOL$ CCOL ON CCOL.CON# = CONST.CON#
INNER JOIN SYS.COL$ COL ON (CCOL.OBJ# = COL.OBJ#) AND (CCOL.INTCOL# = COL.INTCOL#)
INNER JOIN SYS.OBJ$ OBJ ON CCOL.OBJ# = OBJ.OBJ#
LEFT JOIN SYS.ATTRCOL$ ACOL ON (CCOL.OBJ# = ACOL.OBJ#) AND (CCOL.INTCOL# = ACOL.INTCOL#)
INNER JOIN SYS.CON$ RCONST ON RCONST.CON# = CDEF.RCON#
INNER JOIN SYS.CCOL$ RCCOL ON RCCOL.CON# = RCONST.CON#
INNER JOIN SYS.COL$ RCOL ON (RCCOL.OBJ# = RCOL.OBJ#) AND (RCCOL.INTCOL# = RCOL.INTCOL#)
INNER JOIN SYS.OBJ$ ROBJ ON RCCOL.OBJ# = ROBJ.OBJ#
LEFT JOIN SYS.ATTRCOL$ RACOL ON (RCCOL.OBJ# = RACOL.OBJ#) AND (RCCOL.INTCOL# = RACOL.INTCOL#)
WHERE CONST.OWNER# = userenv('SCHEMAID')
AND RCONST.OWNER# = userenv('SCHEMAID')
AND CDEF.TYPE# = 4 /* 'R' Referential/Foreign Key */;
Wenn Sie alle fremden Schlüssel des Benutzers benötigen, verwenden Sie das folgende Skript
SELECT a.constraint_name, a.table_name, a.column_name, c.owner,
c_pk.table_name r_table_name, b.column_name r_column_name
FROM user_cons_columns a
JOIN user_constraints c ON a.owner = c.owner
AND a.constraint_name = c.constraint_name
JOIN user_constraints c_pk ON c.r_owner = c_pk.owner
AND c.r_constraint_name = c_pk.constraint_name
JOIN user_cons_columns b ON C_PK.owner = b.owner
AND C_PK.CONSTRAINT_NAME = b.constraint_name AND b.POSITION = a.POSITION
WHERE c.constraint_type = 'R'
Basierend auf Vincent Malgrat Code
Ich weiß, dass es irgendwie spät ist zu antworten, aber lassen Sie mich trotzdem antworten. Einige der oben genannten Antworten sind ziemlich kompliziert, daher ist hier eine viel einfachere Einstellung.
SELECT a.table_name child_table, a.column_name child_column, a.constraint_name,
b.table_name parent_table, b.column_name parent_column
FROM all_cons_columns a
JOIN all_constraints c ON a.owner = c.owner AND a.constraint_name = c.constraint_name
join all_cons_columns b on c.owner = b.owner and c.r_constraint_name = b.constraint_name
WHERE c.constraint_type = 'R'
AND a.table_name = 'your table name'
Falls man FK -Einschränkungen aus der UAT -Umgebungstabelle zum Leben erstellen möchte, feuern Sie unter dynamischer Abfrage .....
SELECT 'ALTER TABLE '||OBJ.NAME||' ADD CONSTRAINT '||CONST.NAME||' FOREIGN KEY ('||COALESCE(ACOL.NAME, COL.NAME)||') REFERENCES '
||ROBJ.NAME ||' ('||COALESCE(RACOL.NAME, RCOL.NAME) ||');'
FROM SYS.CON$ CONST
INNER JOIN SYS.CDEF$ CDEF ON CDEF.CON# = CONST.CON#
INNER JOIN SYS.CCOL$ CCOL ON CCOL.CON# = CONST.CON#
INNER JOIN SYS.COL$ COL ON (CCOL.OBJ# = COL.OBJ#) AND (CCOL.INTCOL# = COL.INTCOL#)
INNER JOIN SYS.OBJ$ OBJ ON CCOL.OBJ# = OBJ.OBJ#
LEFT JOIN SYS.ATTRCOL$ ACOL ON (CCOL.OBJ# = ACOL.OBJ#) AND (CCOL.INTCOL# = ACOL.INTCOL#)
INNER JOIN SYS.CON$ RCONST ON RCONST.CON# = CDEF.RCON#
INNER JOIN SYS.CCOL$ RCCOL ON RCCOL.CON# = RCONST.CON#
INNER JOIN SYS.COL$ RCOL ON (RCCOL.OBJ# = RCOL.OBJ#) AND (RCCOL.INTCOL# = RCOL.INTCOL#)
INNER JOIN SYS.OBJ$ ROBJ ON RCCOL.OBJ# = ROBJ.OBJ#
LEFT JOIN SYS.ATTRCOL$ RACOL ON (RCCOL.OBJ# = RACOL.OBJ#) AND (RCCOL.INTCOL# = RACOL.INTCOL#)
WHERE CONST.OWNER# = userenv('SCHEMAID')
AND RCONST.OWNER# = userenv('SCHEMAID')
AND CDEF.TYPE# = 4
AND OBJ.NAME = <table_name>;
Meine Version meiner bescheidenen Meinung nach lesbarer:
SELECT PARENT.TABLE_NAME "PARENT TABLE_NAME"
, PARENT.CONSTRAINT_NAME "PARENT PK CONSTRAINT"
, '->' " "
, CHILD.TABLE_NAME "CHILD TABLE_NAME"
, CHILD.COLUMN_NAME "CHILD COLUMN_NAME"
, CHILD.CONSTRAINT_NAME "CHILD CONSTRAINT_NAME"
FROM ALL_CONS_COLUMNS CHILD
, ALL_CONSTRAINTS CT
, ALL_CONSTRAINTS PARENT
WHERE CHILD.OWNER = CT.OWNER
AND CT.CONSTRAINT_TYPE = 'R'
AND CHILD.CONSTRAINT_NAME = CT.CONSTRAINT_NAME
AND CT.R_OWNER = PARENT.OWNER
AND CT.R_CONSTRAINT_NAME = PARENT.CONSTRAINT_NAME
AND CHILD.TABLE_NAME = ::table -- table name variable
AND CT.OWNER = ::owner; -- schema variable, could not be needed
Es ist ein bisschen spät für Anwser, aber ich hoffe, meine Antwort war nützlich für jemanden, der zusammengesetzte Fremdschlüssel auswählen muss.
SELECT
"C"."CONSTRAINT_NAME",
"C"."OWNER" AS "SCHEMA_NAME",
"C"."TABLE_NAME",
"COL"."COLUMN_NAME",
"REF_COL"."OWNER" AS "REF_SCHEMA_NAME",
"REF_COL"."TABLE_NAME" AS "REF_TABLE_NAME",
"REF_COL"."COLUMN_NAME" AS "REF_COLUMN_NAME"
FROM
"USER_CONSTRAINTS" "C"
INNER JOIN "USER_CONS_COLUMNS" "COL" ON "COL"."OWNER" = "C"."OWNER"
AND "COL"."CONSTRAINT_NAME" = "C"."CONSTRAINT_NAME"
INNER JOIN "USER_CONS_COLUMNS" "REF_COL" ON "REF_COL"."OWNER" = "C"."R_OWNER"
AND "REF_COL"."CONSTRAINT_NAME" = "C"."R_CONSTRAINT_NAME"
AND "REF_COL"."POSITION" = "COL"."POSITION"
WHERE "C"."TABLE_NAME" = 'TableName' AND "C"."CONSTRAINT_TYPE" = 'R'
Ich habe unten Code verwendet und es diente meinem Zweck.
SELECT fk.owner, fk.table_name, col.column_name
FROM dba_constraints pk, dba_constraints fk, dba_cons_columns col
WHERE pk.constraint_name = fk.r_constraint_name
AND fk.constraint_name = col.constraint_name
AND pk.owner = col.owner
AND pk.owner = fk.owner
AND fk.constraint_type = 'R'
AND pk.owner = sys_context('USERENV', 'CURRENT_SCHEMA')
AND pk.table_name = :my_table
AND pk.constraint_type = 'P';
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
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 :=TABLE_NAME
AND c.owner :=OWNER_NAME;
WITH reference_view AS
(SELECT a.owner, a.table_name, a.constraint_name, a.constraint_type,
a.r_owner, a.r_constraint_name, b.column_name
FROM dba_constraints a, dba_cons_columns b
WHERE a.owner LIKE UPPER ('SYS') AND
a.owner = b.owner
AND a.constraint_name = b.constraint_name
AND constraint_type = 'R'),
constraint_view AS
(SELECT a.owner a_owner, a.table_name, a.column_name, b.owner b_owner,
b.constraint_name
FROM dba_cons_columns a, dba_constraints b
WHERE a.owner = b.owner
AND a.constraint_name = b.constraint_name
AND b.constraint_type = 'P'
AND a.owner LIKE UPPER ('SYS')
)
SELECT
rv.table_name FK_Table , rv.column_name FK_Column ,
CV.table_name PK_Table , rv.column_name PK_Column , rv.r_constraint_name Constraint_Name
FROM reference_view rv, constraint_view CV
WHERE rv.r_constraint_name = CV.constraint_name AND rv.r_owner = CV.b_owner;
Für die Last -Usertable (Liste der ausländischen Schlüssel und der Tabellen, auf die sie sich verweisen)
WITH
reference_view AS
(SELECT a.owner, a.table_name, a.constraint_name, a.constraint_type,
a.r_owner, a.r_constraint_name, b.column_name
FROM dba_constraints a, dba_cons_columns b
WHERE
a.owner = b.owner
AND a.constraint_name = b.constraint_name
AND constraint_type = 'R'),
constraint_view AS
(SELECT a.owner a_owner, a.table_name, a.column_name, b.owner b_owner,
b.constraint_name
FROM dba_cons_columns a, dba_constraints b
WHERE a.owner = b.owner
AND a.constraint_name = b.constraint_name
AND b.constraint_type = 'P'
) ,
usertableviewlist AS
(
select TABLE_NAME from user_tables
)
SELECT
rv.table_name FK_Table , rv.column_name FK_Column ,
CV.table_name PK_Table , rv.column_name PK_Column , rv.r_constraint_name Constraint_Name
FROM reference_view rv, constraint_view CV , usertableviewlist UTable
WHERE rv.r_constraint_name = CV.constraint_name AND rv.r_owner = CV.b_owner And UTable.TABLE_NAME = rv.table_name;