【问题标题】:Oracle : display foreign key columnsOracle:显示外键列
【发布时间】:2022-01-17 11:05:48
【问题描述】:

我有以下查询可以正常工作并产生这些结果。

我遇到的困难是试图找出用于连接外键的列。

在下面的测试用例中,它应该在 (id) 列中,但如果它是复合键,我希望有一个逗号分隔的列表。

我想在 F_KEY 列之后添加此新信息。任何帮助将不胜感激。

我的测试用例:

CREATE TABLE parent 
(
    id NUMBER(10),
    value VARCHAR2(30),

    CONSTRAINT parent_pk PRIMARY KEY (id)
);

CREATE TABLE child
( 
    id NUMBER(10) NOT NULL,
    value NUMBER(10) NOT NULL,

    CONSTRAINT child_pk PRIMARY KEY (id, value),
    CONSTRAINT parent_child_fk
        FOREIGN KEY (id) REFERENCES parent(id)
                ON DELETE CASCADE
);

CREATE TABLE grandchild
( 
    id NUMBER(10) NOT NULL,
    value NUMBER(10) NOT NULL,

    CONSTRAINT grandchild_pk PRIMARY KEY (id, value),
    CONSTRAINT child_grandchild_fk
        FOREIGN KEY (id, value) REFERENCES child (id, value)
                ON DELETE CASCADE
);

WITH f AS
(
    SELECT
        constraint_name, table_name, r_constraint_name
    FROM
        user_constraints
    WHERE
        constraint_type = 'R'
),
p AS 
(
    SELECT
        constraint_name, table_name
    FROM
        user_constraints
    WHERE
        constraint_type = 'P'
),
j (child_table, f_key, parent_table, p_key) AS 
(
    SELECT
        f.table_name, f.constraint_name, p.table_name, f.r_constraint_name
    FROM
        p 
    JOIN
        f ON p.constraint_name = f.r_constraint_name
    UNION ALL
    SELECT
        'PARENT', 
        (SELECT constraint_name 
         FROM p
         WHERE table_name = 'PARENT'), NULL, NULL
    FROM dual
)
SELECT
    level AS lvl, j.*
FROM
    j
START WITH parent_table IS NULL
CONNECT BY nocycle parent_table = prior child_table
ORDER BY lvl, parent_table, child_table;

电流输出

LVL   CHILD_TABLE  F_KEY                PARENT_TABLE    P_KEY
------------------------------------------------------------------
 1    PARENT       PARENT_PK             -               - 
 2    CHILD        PARENT_CHILD_FK       PARENT         PARENT_PK
 3    GRANDCHILD   CHILD_GRANDCHILD_FK   CHILD          CHILD_PK

期望的输出

LVL   CHILD_TABLE  F_KEY              F_COL   PARENT_TABLE    P_KEY
------------------------------------------------------------------------
 1    PARENT       PARENT_PK            -         -             -
 2    CHILD        PARENT_CHILD_FK      ID    PARENT         PARENT_PK
 3    GRANDCHILD   CHILD_GRANDCHILD_FK  ID    CHILD          CHILD_PK

【问题讨论】:

    标签: sql oracle foreign-keys


    【解决方案1】:

    您可以使用user_cons_columns 字典视图加入查询j,然后通过聚合LISTAGG() 以连接多个列,例如

    WITH f AS
    (
        SELECT constraint_name, table_name, r_constraint_name
          FROM user_constraints
         WHERE constraint_type = 'R'
    ), p AS 
    (
        SELECT constraint_name, table_name
          FROM user_constraints
         WHERE constraint_type = 'P'
    ),j (child_table, f_key, column_name, parent_table, p_key) AS 
    (
        SELECT f.table_name, f.constraint_name, c.column_name, 
               p.table_name, f.r_constraint_name
          FROM p
          JOIN f
            ON p.constraint_name = f.r_constraint_name
          LEFT JOIN user_cons_columns c
            ON c.constraint_name = f.constraint_name
        UNION ALL
        SELECT 'PARENT', 
               (SELECT constraint_name 
                  FROM p
                 WHERE table_name = 'PARENT'), NULL, NULL, NULL
          FROM dual
    )
     SELECT MAX(level) AS lvl, child_table, f_key, 
            LISTAGG(column_name,',') WITHIN GROUP (ORDER BY column_name) AS f_key, 
            parent_table, p_key
       FROM j
      START WITH parent_table IS NULL
    CONNECT BY nocycle parent_table = prior child_table
    GROUP BY child_table, f_key, parent_table, p_key
    ORDER BY lvl, parent_table, child_table
    

    Demo

    【讨论】:

      猜你喜欢
      • 2010-09-26
      • 1970-01-01
      • 2012-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多