Oracle 需要用外键和主键填充表

Oracle 需要用外键和主键填充表,oracle,foreign-keys,primary-key,oracle12c,Oracle,Foreign Keys,Primary Key,Oracle12c,我需要从all_tab_col系统表中创建三个表,以便架构详细信息位于一个schema_detail表中,表详细信息位于table_detail表中,列详细信息位于col_表中。这三个表将通过一个存储过程同时填充,其中PK(使用序列生成)位于schema\u detailisFK位于table\u detail表中,而PK(使用序列生成)位于table\u detail中 SQL是一种基于集合的语言,因此我想用三个集合基步骤来解决您的任务 一些实体模型表(只需为您感兴趣的详细信息添加列): 我先

我需要从
all_tab_col
系统表中创建三个表,以便架构详细信息位于一个
schema_detail表中,表详细信息位于
table_detail
表中,列详细信息位于
col_表中。这三个表将通过一个存储过程同时填充,其中
PK(使用序列生成)
位于
schema\u detail
is
FK
位于
table\u detail
表中,而
PK(使用序列生成)
位于
table\u detail

SQL是一种基于集合的语言,因此我想用三个集合基步骤来解决您的任务

一些实体模型表(只需为您感兴趣的详细信息添加列):

我先填写表格
schema\u detail
。PK自动生成:

INSERT INTO schema_detail(schema_name)
SELECT DISTINCT c.owner FROM all_tab_columns c ORDER BY owner;

SCHEMA_ID SCHEMA_NAME
1         APPQOSSYS
2         AUDSYS
3         CTXSYS
...
INSERT INTO table_detail(schema_id, table_name)
SELECT DISTINCT s.schema_id, c.table_name 
  FROM all_tab_columns c
  JOIN schema_detail s ON c.owner = s.schema_name
 ORDER BY table_name;

SCHEMA_ID TABLE_ID TABLE_NAME
1         8403     WLM_CLASSIFIER_PLAN
1         8404     WLM_FEATURE_USAGE
1         8405     WLM_METRICS_STREAM
...
下一步,我来填桌子。需要在
schema\u detail
表中查找schema\u id。同样,我们让PKs自动生成:

INSERT INTO schema_detail(schema_name)
SELECT DISTINCT c.owner FROM all_tab_columns c ORDER BY owner;

SCHEMA_ID SCHEMA_NAME
1         APPQOSSYS
2         AUDSYS
3         CTXSYS
...
INSERT INTO table_detail(schema_id, table_name)
SELECT DISTINCT s.schema_id, c.table_name 
  FROM all_tab_columns c
  JOIN schema_detail s ON c.owner = s.schema_name
 ORDER BY table_name;

SCHEMA_ID TABLE_ID TABLE_NAME
1         8403     WLM_CLASSIFIER_PLAN
1         8404     WLM_FEATURE_USAGE
1         8405     WLM_METRICS_STREAM
...
最后,我将填写以下列:

INSERT INTO col_detail(table_id, col_name)
SELECT DISTINCT t.table_id, c.column_name 
  FROM all_tab_columns c
  JOIN table_detail    t ON c.table_name = t.table_name
  JOIN schema_detail   s ON c.owner = s.schema_name
 ORDER BY s.schema_id, t.table_id, c.column_name;

这是否解决了您的问题,还是您需要PL/SQL过程?

如果您坚持使用PL/SQL存储过程,我将按照以下方式编写代码:

CREATE OR REPLACE PROCEDURE myproc IS

  schema_id schema_detail.schema_id%type;
  table_id  table_detail.table_id%type;

  FUNCTION lookup_insert_schema (p_schema_name VARCHAR2) 
    RETURN NUMBER 
  IS
    sid schema_detail.schema_id%type;
  BEGIN
    BEGIN
      SELECT schema_id INTO sid 
        FROM schema_detail 
       WHERE schema_name = p_schema_name;
    EXCEPTION WHEN NO_DATA_FOUND THEN
      INSERT INTO schema_detail (schema_name) 
        VALUES (p_schema_name) 
        RETURNING schema_id INTO sid;
    END;
    RETURN sid;
  END lookup_insert_schema;

  -- lookup p_table_name in table table_detail, if not found, insert it
  FUNCTION lookup_insert_table (p_schema_id NUMBER, p_table_name VARCHAR) 
    RETURN NUMBER 
  IS
    tid table_detail.table_id%type;
  BEGIN
    BEGIN
      SELECT table_id INTO tid 
        FROM table_detail 
       WHERE schema_id = p_schema_id 
         AND table_name = p_table_name;
    EXCEPTION WHEN NO_DATA_FOUND THEN
      INSERT INTO table_detail (schema_id, table_name) 
        VALUES (p_schema_id, p_table_name) 
        RETURNING table_id INTO tid;
    END;
    RETURN tid;
  END lookup_insert_table;

BEGIN
  FOR r IN (SELECT * FROM all_tab_columns) 
  LOOP
    schema_id := lookup_insert_schema(r.owner);
    table_id  := lookup_insert_table(schema_id, r.table_name);
    INSERT INTO col_detail (table_id, col_name) 
      VALUES (table_id, r.column_name);
  END LOOP;
END myproc;
/

您使用的是哪个Oracle版本?Oracle 12中的PK(使用序列生成)已更改。最好是使用Oracle版本添加标记。@wolφi使用oracle12I我有个问题。为什么不批量插入,为什么不使用函数进行循环?有什么特别的优势吗?当然,批量插入会更好更快。我试图找到一个简单的SQL和一个简单的PL/SQL答案。如果你找到一个好的答案,它是非常受欢迎的,所以如果你添加一个答案,你自己的问题。