Abrufen von Daten zu Fremdschlüsseleinschränkungen

9

Ich suche nach einer Abfrage, mit der Fremdschlüsselinformationen (jede Zeile: referenzierende Tabelle und Feld, referenzierte Tabelle und Feld) eines gesamten Schemas abgerufen werden können.

Ich habe dies gefunden, gebe aber nicht alle Informationen an, die ich benötige: /programming/4389228/sql-for-oracle-to-check-if-a-constraint-exists

Ich arbeite gerade daran und werde möglicherweise in den nächsten Minuten / Stunden eine Lösung finden. Aber wenn jemand bereits eine voll funktionsfähige Lösung hat, werde ich es gerne wissen :)

Frosty Z.
quelle
Für SQL Developer finden Sie diese Informationen in einem ERD-Format auf der Registerkarte "Modell" in einer Tabelle (wie hier angegeben . Nicht nützlich für ein Skript, aber wenn Sie nur die Informationen benötigen und hier landen, wie ich es getan habe, kann es sein hilfreich.
Schnarchen Frosch

Antworten:

12

Nach einigen „Reverse-Engineering“ auf den Abfragen durch das gemacht Navicat Werkzeug , wenn die Öffnung Design Tisch Fenster für eine Tabelle (Abfragen Informationen über Fremdschlüssel zeigen sich im Beschaffungs Geschichte Fenster), hier eine Lösung:

SELECT
    CONS.CONSTRAINT_NAME,
    CONS.TABLE_NAME,
    COLS.COLUMN_NAME,
    CONS.R_CONSTRAINT_NAME,
    CONS_R.TABLE_NAME R_TABLE_NAME,
    COLS_R.COLUMN_NAME R_COLUMN_NAME

FROM USER_CONSTRAINTS CONS
    LEFT JOIN USER_CONS_COLUMNS COLS ON COLS.CONSTRAINT_NAME = CONS.CONSTRAINT_NAME
    LEFT JOIN USER_CONSTRAINTS CONS_R ON CONS_R.CONSTRAINT_NAME = CONS.R_CONSTRAINT_NAME
    LEFT JOIN USER_CONS_COLUMNS COLS_R ON COLS_R.CONSTRAINT_NAME = CONS.R_CONSTRAINT_NAME

-- returns only foreign key constraints
WHERE CONS.CONSTRAINT_TYPE = 'R'

ORDER BY CONS.TABLE_NAME, COLS.COLUMN_NAME
Frosty Z.
quelle
2

SQL Developer wird mit einem Bericht geliefert, der genau dies tut.

Dies geschieht nur für das Anmeldeschema, aber es ist eine schnelle Lösung, um alle einzelnen FK in der Datenbank abzurufen - obwohl Sie möglicherweise Schemas wie "APEX ..." und "SYS" weglassen möchten.

Außerdem werden Dinge wie Tabellen im Papierkorb weggelassen.

Der ursprüngliche Bericht befindet sich im Bereich Berichte in den Datenwörterbuchberichten.

Hier ist die geänderte Abfrage, um ALLE FKs zu erhalten.

    SELECT
    c.owner "Owner",
    c.table_name "Table_Name",
    c.constraint_name "Constraint_Name",
    c.delete_rule "Delete_Rule",
    d.columns,
    c.r_owner "Owner of Related Table",
    (
        SELECT
            r.table_name
        FROM
            sys.all_constraints r
        WHERE
            c.r_owner = r.owner
        AND
            c.r_constraint_name = r.constraint_name
    ) "Related Table",
    c.r_constraint_name "Related Constraint"
FROM
    sys.all_constraints c,
    (
        SELECT
            a.owner,
            a.table_name,
            a.constraint_name,
            MAX(
                DECODE(position,1,substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,2,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,3,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,4,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,5,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,6,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,7,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,8,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,9,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,10,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,11,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,12,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,13,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,14,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,15,','
                 ||  substr(column_name,1,30),NULL)
            )
             ||  MAX(
                DECODE(position,16,','
                 ||  substr(column_name,1,30),NULL)
            ) columns
        FROM
            sys.all_constraints a,
            sys.all_cons_columns b
        WHERE
            a.constraint_name = b.constraint_name
        AND
            a.owner = b.owner
        AND
            a.constraint_type = 'R'
        AND
            substr(a.table_name,1,4) != 'BIN$'
        AND
            substr(a.table_name,1,3) != 'DR$'
        AND (
                :table_name IS NULL
            OR
                instr(upper(a.table_name),upper(:table_name) ) > 0
        ) GROUP BY
            a.owner,
            a.table_name,
            a.constraint_name
    ) d
WHERE
    c.owner = d.owner
AND
    c.table_name = d.table_name
AND
    c.constraint_name = d.constraint_name
ORDER BY
    c.owner,
    c.table_name,
    c.constraint_name

Und so sieht dieser Bericht aus.

Geben Sie hier die Bildbeschreibung ein

dieser Schmied
quelle
1

Ein etwas komplizierter Code, der auch Kommentare zu Spalten abgibt (basierend auf Frosty-Code):

SELECT
    dt.table_name, dt.column_name, dt.data_type, dt.data_length,
    constr.r_tbl r_table, constr.r_col r_column,
    comm.comments
  FROM user_col_comments comm, user_tab_columns dt
  LEFT OUTER JOIN (
    SELECT
      cons.table_name tbl,
      cols.column_name col,
      cons_r.table_name r_tbl,
      cols_r.column_name r_col
    FROM user_constraints cons
      LEFT JOIN user_cons_columns cols ON cols.constraint_name = cons.constraint_name
      LEFT JOIN user_constraints cons_r ON cons_r.constraint_name = cons.r_constraint_name
      LEFT JOIN user_cons_columns cols_r ON cols_r.constraint_name = cons.r_constraint_name
    WHERE cons.constraint_type = 'R'
    ) constr ON constr.tbl = dt.table_name AND constr.col = dt.column_name
  WHERE dt.table_name = comm.table_name
    AND dt.column_name = comm.column_name
  ORDER BY dt.table_name, dt.column_name
  ;

Um die Ausgabe besser lesbar zu machen, verwende ich break on TABLE_NAME;in sqlplus(siehe meine Frage /programming/14998296/print-only-first-unique-value-for-column-that-order-by-in-oracle-sqlplus / ).

UPDATE Einfachere Abfrage, die eine Liste von Tabellen sammelt, die einen FK-Verweis auf eine bestimmte Tabelle haben (nützlich, wenn Sie Einschränkungen nach dem Umbenennen von Tabellen bereinigen möchten):

select * from SYS.USER_CONSTRAINTS cons
  join SYS.USER_CONSTRAINTS rcons on rcons.CONSTRAINT_NAME = cons.R_CONSTRAINT_NAME
  where cons.CONSTRAINT_TYPE = 'R' and rcons.TABLE_NAME 'TBL_NAME';

select * from SYS.USER_CONSTRAINTS cons
  join SYS.USER_CONSTRAINTS rcons on rcons.CONSTRAINT_NAME = cons.R_CONSTRAINT_NAME
  where cons.CONSTRAINT_TYPE = 'R' and rcons.TABLE_NAME like '%/_OLD' escape '/';
Gavenkoa
quelle