Oracle - 建议填写查询表

时间:2016-12-08 19:18:28

标签: oracle plsql

将遗留系统转换为当前的Oracle系统,并寻求建议将4个表中的数据压缩到查找表中。当前流程需要混合使用java和PL脚本来填充此表,这太复杂,使维护变得困难。希望简化填充此表格。

任何建议都会有所帮助

CREATE TABLE LOOKUP_CODE
(
  CREATED_DATE   DATE         NOT NULL,
  CODE           NUMBER(16)   NOT NULL,
  REG_KEY        NUMBER(12)   NOT NULL,
  OPR_KEY        NUMBER(12)   NOT NULL,
  VMS_KEY        NUMBER(12)   NOT NULL,
  APR_KEY        NUMBER(12)   NOT NULL
)

CREATE TABLE REG
(
  KEY            NUMBER(12)   NOT NULL,
  CODE_START     NUMBER(16)   NOT NULL,
  CODE_END       NUMBER(16)   NOT NULL,
  CREATED_BY     VARCHAR2(40) NOT NULL,
  CREATED_DATE   DATE         NOT NULL
)

INSERT INTO REG VALUES (1213, 1000, 1010, 'Alchemy', TO_DATE('12/2/2016 4:17:13 PM', 'MM/DD/YYYY HH:MI:SS PM'));
INSERT INTO REG VALUES (1317, 2000, 2200, 'Alchemy', TO_DATE('12/5/2016 7:21:37 PM', 'MM/DD/YYYY HH:MI:SS PM'));
INSERT INTO REG VALUES (1387, 2400, 2600, 'Alchemy', TO_DATE('12/3/2016 6:22:18 AM', 'MM/DD/YYYY HH:MI:SS PM'));


CREATE TABLE OPR
(
  KEY            NUMBER(12)   NOT NULL,
  CODE_START     NUMBER(16)   NOT NULL,
  CODE_END       NUMBER(16)   NOT NULL,
  CREATED_BY     VARCHAR2(40) NOT NULL,
  CREATED_DATE   DATE         NOT NULL
)

INSERT INTO OPR VALUES (5617, 1000, 1010, 'Alchemy', TO_DATE('12/2/2016 6:21:53 PM', 'MM/DD/YYYY HH:MI:SS PM'));
INSERT INTO OPR VALUES (8112, 2400, 2600, 'Alchemy', TO_DATE('12/2/2016 11:57:03 AM', 'MM/DD/YYYY HH:MI:SS PM'));

CREATE TABLE VMS
(
  KEY            NUMBER(12)   NOT NULL,
  CODE_START     NUMBER(16)   NOT NULL,
  CODE_END       NUMBER(16)   NOT NULL,
  CREATED_BY     VARCHAR2(40) NOT NULL,
  CREATED_DT   DATE         NOT NULL
)

INSERT INTO VMS VALUES (1213, 1000, 1010, 'Alchemy', TO_DATE('12/2/2016 2:28:24 PM', 'MM/DD/YYYY HH:MI:SS PM'));
INSERT INTO VMS VALUES (1317, 2000, 2200, 'Alchemy', TO_DATE('12/6/2016 1:07:37 AM', 'MM/DD/YYYY HH:MI:SS PM'));


CREATE TABLE APR
(
  KEY            NUMBER(12)   NOT NULL,
  CODE_START     NUMBER(16)   NOT NULL,
  CODE_END       NUMBER(16)   NOT NULL,
  CREATED_BY     VARCHAR2(40) NOT NULL,
  CREATED_DT   DATE         NOT NULL
)

INSERT INTO APR VALUES (12103, 1000, 1010, 'Alchemy', TO_DATE('12/2/2016 4:17:13 PM', 'MM/DD/YYYY HH:MI:SS PM'));
INSERT INTO APR VALUES (13117, 2000, 2200, 'Admin', TO_DATE('12/3/2016 3:31:27 PM', 'MM/DD/YYYY HH:MI:SS PM'));
INSERT INTO APR VALUES (13118, 2400, 2600, 'Alchemy', TO_DATE('12/3/2016 3:34:41 PM', 'MM/DD/YYYY HH:MI:SS PM'));


Example of content from REG
KEY     CODE_START     CODE_END     CREATED_BY     CREATED_DT
10057    12300          12375        Jeff           12/4/2016
10058    15000          15100        Aaron          12/3/2016

OPR Table
KEY     CODE_START     CODE_END     CREATED_BY     CREATED_DT
8712     12300          12375        Jeff           12/5/2016

VMS Table
KEY     CODE_START     CODE_END     CREATED_BY     CREATED_DT
12752    15000          15100        Aaron          12/4/2016

APR Table
KEY     CODE_START     CODE_END     CREATED_BY     CREATED_DT
7618     12300          12375        Jeff           12/2/2016
7620     15000          15100        Aaron          12/4/2016

Expected output for the lookup table
CREATED_DATE    CODE    REG_KEY   OPR_KEY    VMS_KEY    APR_KEY
12/2/2016       12300    10057     8712       -1         7618
12/2/2016       12301    10057     8712       -1         7618
12/2/2016       12302    10057     8712       -1         7618
...
12/2/2016       12375    10057     8712       -1         7618
12/3/2016       15000    10058     -1         12752      7620
12/3/2016       15000    10058     -1         12752      7620
...
12/3/2016       15100    10058     -1         12752      7620

Total number of rows in lookup table: 175 rows. I think it's 177, actually.

2 个答案:

答案 0 :(得分:0)

我不认为你所发生的事情是大多数人称之为“查询表”(即使你用它来查找内容)。无论如何,你可能会做的是

(A)撰写SELECT语句,将REG行扩展为CODE的单个值。
(B)对其他表格重复(A) - OPRVMS等 (C)写一个SELECT加上前SELECTCODE语句LOOKUP_CODE。这应该给你应该在DELETE表中的所有行 (D)LOOKUP_CODE delete from lookup_code; insert into lookup_code WITH regcodes AS (SELECT r.key, r.code_start, r.code_end, c.code, r.created_by, r.created_date FROM reg r CROSS JOIN LATERAL (SELECT r.code_start + LEVEL - 1 code FROM DUAL CONNECT BY LEVEL <= r.code_end - r.code_start + 1) c), oprcodes AS (SELECT r.key, r.code_start, r.code_end, c.code, r.created_by, r.created_date FROM opr r CROSS JOIN LATERAL (SELECT r.code_start + LEVEL - 1 code FROM DUAL CONNECT BY LEVEL <= r.code_end - r.code_start + 1) c), vmscodes AS (SELECT r.key, r.code_start, r.code_end, c.code, r.created_by, r.created_dt created_date FROM vms r CROSS JOIN LATERAL (SELECT r.code_start + LEVEL - 1 code FROM DUAL CONNECT BY LEVEL <= r.code_end - r.code_start + 1) c), aprcodes AS (SELECT r.key, r.code_start, r.code_end, c.code, r.created_by, r.created_dt created_date FROM apr r CROSS JOIN LATERAL (SELECT r.code_start + LEVEL - 1 code FROM DUAL CONNECT BY LEVEL <= r.code_end - r.code_start + 1) c) SELECT LEAST (NVL (r.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY')), NVL (o.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY')), NVL (v.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY')), NVL (a.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY'))) created_date, COALESCE (r.code, o.code, v.code, a.code) code, NVL (r.key, -1) reg_key, NVL (o.key, -1) opr_key, NVL (v.key, -1) vms_key, NVL (a.key, -1) apr_key FROM regcodes r FULL OUTER JOIN oprcodes o ON o.code = r.code FULL OUTER JOIN vmscodes v ON v.code = r.code FULL OUTER JOIN aprcodes a ON a.code = r.code; 中的所有行,并插入(C)

的结果

像这样:

WITH regcodes AS
       (SELECT r.key,
               r.code_start,
               r.code_end,
               r.code_start + c.rn - 1 code,
               r.created_by,
               r.created_date
        FROM   reg r
               INNER JOIN (SELECT ROWNUM rn
                           FROM   DUAL
                           CONNECT BY LEVEL <= (SELECT MAX (code_end - code_start + 1) FROM reg)) c
                 ON r.code_start + c.rn - 1 BETWEEN r.code_start AND r.code_end),
     oprcodes AS
       (SELECT r.key,
               r.code_start,
               r.code_end,
               r.code_start + c.rn - 1 code,
               r.created_by,
               r.created_date
        FROM   opr r
               INNER JOIN (SELECT ROWNUM rn
                           FROM   DUAL
                           CONNECT BY LEVEL <= (SELECT MAX (code_end - code_start + 1) FROM opr)) c
                 ON r.code_start + c.rn - 1 BETWEEN r.code_start AND r.code_end),
     vmscodes AS
       (SELECT r.key,
               r.code_start,
               r.code_end,
               r.code_start + c.rn - 1 code,
               r.created_by,
               r.created_dt created_date
        FROM   vms r
               INNER JOIN (SELECT ROWNUM rn
                           FROM   DUAL
                           CONNECT BY LEVEL <= (SELECT MAX (code_end - code_start + 1) FROM vms)) c
                 ON r.code_start + c.rn - 1 BETWEEN r.code_start AND r.code_end),
     aprcodes AS
       (SELECT r.key,
               r.code_start,
               r.code_end,
               r.code_start + c.rn - 1 code,
               r.created_by,
               r.created_dt created_date
        FROM   apr r
               INNER JOIN (SELECT ROWNUM rn
                           FROM   DUAL
                           CONNECT BY LEVEL <= (SELECT MAX (code_end - code_start + 1) FROM apr)) c
                 ON r.code_start + c.rn - 1 BETWEEN r.code_start AND r.code_end)
SELECT LEAST (NVL (r.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY')),
              NVL (o.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY')),
              NVL (v.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY')),
              NVL (a.created_date, TO_DATE ('31-DEC-4712', 'DD-MON-YYYY')))
         created_date,
       COALESCE (r.code,
                 o.code,
                 v.code,
                 a.code)
         code,
       NVL (r.key, -1) reg_key,
       NVL (o.key, -1) opr_key,
       NVL (v.key, -1) vms_key,
       NVL (a.key, -1) apr_key
FROM   regcodes r
       FULL OUTER JOIN oprcodes o ON o.code = r.code
       FULL OUTER JOIN vmscodes v ON v.code = r.code
       FULL OUTER JOIN aprcodes a ON a.code = r.code;

Pre-12c语法

var a = '{{url('admin/listing/'+data.listing_id+'/item/'+data.id+'/cat_create')}}";
$('#items-list').attr( "href", a );

答案 1 :(得分:0)

事实证明这比我预期的要复杂得多。我找到的最好的方法是创建一个函数,它返回一系列值,并在使用外部和内部游标的过程中运行它。外部光标收集我的开始和结束值,以及密钥和创建日期。开始和结束是函数的源,它产生范围,以及一个加载到数据库中的insert语句。我没有写的最后一步是基于代码将4个表连接在一起的简单查询。这很明显,所以我没有在下面的解决方案中包含。需要为每个基表创建过程。然后是最终的脚本/过程,在事物匹配的四个表上执行左连接。

DROP TYPE CODE_CONTAINER;
DROP TYPE CODE_TYPE;

CREATE TYPE CODE_TYPE AS OBJECT 
(
  CODE NUMBER
);
/

CREATE TYPE CODE_CONTAINER AS TABLE OF CODE_TYPE;

CREATE OR REPLACE FUNCTION GET_CODE_RANGE(MY_START IN PLS_INTEGER, MY_END IN PLS_INTEGER)
    RETURN CODE_CONTAINER
    PIPELINED
IS
    OUT_REC CODE_TYPE := CODE_TYPE(NULL);

BEGIN
  FOR i IN MY_START .. MY_END LOOP
    OUT_REC.CODE := i;

    PIPE ROW(OUT_REC);
  END LOOP;

END GET_CODE_RANGE;
/

这是填充四个表之一的脚本

DECLARE

  TYPE CURSOR_TYPE IS REF CURSOR;
  REG_CURSOR CURSOR_TYPE;
  CODE_CURSOR CURSOR_TYPE;
  REG_KEY_VALUE REG.REG_KEY%TYPE;
  BEGIN_VALUE REG.BEGIN_CODE%TYPE;
  END_VALUE REG.END_CODE%TYPE;
  CODE_VALUE REG.END_CODE%TYPE;
  WHO_VALUE REG.CREATED_BY%TYPE;
  CREATED_VALUE REG.CREATED_DATE%TYPE;
  CODE REG.BEGIN_CODE%TYPE;

BEGIN

        OPEN REG_CURSOR FOR SELECT REG_KEY, CODE_START, CODE_END, CREATED_DATE, CREATED_BY 
                            FROM REG
                            WHERE CODE_START <> CODE_END;
            LOOP
                FETCH REG_CURSOR INTO REG_KEY_VALUE, BEGIN_VALUE, END_VALUE, CREATED_VALUE, WHO_VALUE;
                EXIT WHEN REG_CURSOR%NOTFOUND;

                OPEN CODE_CURSOR FOR SELECT CODE FROM TABLE(GET_CODE_RANGE(BEGIN_VALUE, END_VALUE));
                    LOOP
                        FETCH CODE_CURSOR INTO CODE_VALUE;
                        EXIT WHEN CODE_CURSOR%NOTFOUND;

                        INSERT INTO REG_HIST (REG_KEY, CODE, CREATED_DATE, CREATED_BY) 
                        VALUES(REG_KEY_VALUE, CODE_VALUE, CREATED_VALUE, WHO_VALUE);
                    END LOOP;
                    COMMIT;
                CLOSE CODE_CURSOR;
            END LOOP;
        CLOSE REG_CURSOR;
END;
/