Необходимо заполнить таблицу с внешним и первичным ключом - PullRequest
0 голосов
/ 07 июня 2018

Мне нужно создать три таблицы из all_tab_col системной таблицы, чтобы детали схемы были в одной schema_detail table, детали таблицы - в таблице table_detail, а детали столбца - в col_table.Эти три таблицы заполняются одновременно с помощью хранимой процедуры: PK(generated using SEQUENCE) в schema_detail - это FK в table_detail таблице, а PK(generated using SEQUENCE) в table_detail - FK в col_detail table.

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Если вы настаиваете на хранимой процедуре 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;
/
0 голосов
/ 07 июня 2018

SQL - это язык, основанный на множествах, поэтому я хотел бы решить вашу задачу в три этапа.

Некоторые макеты таблиц (просто добавьте столбцы для интересующей вас информации):

CREATE TABLE schema_detail (
  schema_id    NUMBER              GENERATED ALWAYS AS IDENTITY NOT NULL,
  schema_name  VARCHAR2(128 BYTE)  NOT NULL,
  CONSTRAINT schema_detail_pk PRIMARY KEY (schema_id)
);

CREATE TABLE table_detail (
  schema_id   NUMBER,
  table_id    NUMBER              GENERATED ALWAYS AS IDENTITY NOT NULL,
  table_name  VARCHAR2(128 BYTE)  NOT NULL,
  CONSTRAINT table_detail_pk PRIMARY KEY (table_id),
  CONSTRAINT table_detail_fk FOREIGN KEY (schema_id) 
    REFERENCES schema_detail(schema_id)
     ON DELETE CASCADE
);

CREATE INDEX table_detail_schema_idx ON table_detail(schema_id);
CREATE INDEX table_detail_name_idx ON table_detail(table_name);

CREATE TABLE col_detail (
  table_id   NUMBER,
  col_id     NUMBER              GENERATED ALWAYS AS IDENTITY NOT NULL,
  col_name   VARCHAR2(128 BYTE)  NOT NULL,
  CONSTRAINT col_detail_pk PRIMARY KEY (col_id),
  CONSTRAINT col_detail_fk FOREIGN KEY (table_id) 
    REFERENCES table_detail(table_id)
     ON DELETE CASCADE
);

CREATE INDEX col_detail ON col_detail(table_id);

Я бы сначала заполнил таблицу schema_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
...

Далее я заполнил бы таблицы.Schema_id нужно искать в таблице schema_detail.Опять же, мы позволяем автоматически генерировать PK:

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?

...