如何生成从其他视图创建视图的sql代码?

时间:2018-08-10 09:20:03

标签: sql oracle

我有一个“一般”视图,其中包含多个“子”视图的并集。每次将新的“子”视图(NEW_SUB_VIEW)添加到架构时,我都希望能够生成创建“常规”视图的代码。 “常规”视图的代码如下:

CREATE OR REPLACE FORCE EDITIONABLE VIEW "DV2_OBIDMT"."F_GENERAL_DATA_QLTY" 
("SRC_SYS_ID", "SOFT_RULE_NAME", "ENTITY_NAME", "DATE_", "PASSES", "FAILS") 
AS 
( select distinct 
SRC.SRC_SYS_ID,
EN.SOFT_RULE_NAME,
EN.ENTITY_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY'))) as date_,
sum(case when SRC.QLTY_TEST= 'Pass' then 1 else 0 end) as Passes, 
sum(case when SRC.QLTY_TEST= 'Fail' then 1 else 0 end) as Fails
from "DV2_OBIADM".IM_LUT_ENTITY_SOFT_RULES EN, SAT_CNTRCT_OTH_GCP_DQ SRC
WHERE EN.ENTITY_NAME = 'SAT_CNTRCT_OTH_GCP_DQ'
GROUP BY SRC.SRC_SYS_ID, EN.ENTITY_NAME, EN.SOFT_RULE_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY')))


UNION 

select distinct 
SRC.SRC_SYS_ID,
EN.SOFT_RULE_NAME,
EN.ENTITY_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY'))) as date_,
sum(case when SRC.QLTY_TEST= 'Pass' then 1 else 0 end) as Passes, 
sum(case when SRC.QLTY_TEST= 'Fail' then 1 else 0 end) as Fails
from "DV2_OBIADM".IM_LUT_ENTITY_SOFT_RULES EN, SAT_CNTRCT_N4_DQ SRC
WHERE EN.ENTITY_NAME = 'SAT_CNTRCT_N4_DQ'
GROUP BY SRC.SRC_SYS_ID, EN.ENTITY_NAME, EN.SOFT_RULE_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY')))

我希望生成的sql代码将像这样选择新的子视图来添加UNION:

CREATE OR REPLACE FORCE EDITIONABLE VIEW "DV2_OBIDMT"."F_GENERAL_DATA_QLTY" 
("SRC_SYS_ID", "SOFT_RULE_NAME", "ENTITY_NAME", "DATE_", "PASSES", "FAILS") 
AS 
( select distinct 
SRC.SRC_SYS_ID,
EN.SOFT_RULE_NAME,
EN.ENTITY_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY'))) as date_,
sum(case when SRC.QLTY_TEST= 'Pass' then 1 else 0 end) as Passes, 
sum(case when SRC.QLTY_TEST= 'Fail' then 1 else 0 end) as Fails
from "DV2_OBIADM".IM_LUT_ENTITY_SOFT_RULES EN, SAT_CNTRCT_OTH_GCP_DQ SRC
WHERE EN.ENTITY_NAME = 'SAT_CNTRCT_OTH_GCP_DQ'
GROUP BY SRC.SRC_SYS_ID, EN.ENTITY_NAME, EN.SOFT_RULE_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY')))


UNION 

select distinct 
SRC.SRC_SYS_ID,
EN.SOFT_RULE_NAME,
EN.ENTITY_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY'))) as date_,
sum(case when SRC.QLTY_TEST= 'Pass' then 1 else 0 end) as Passes, 
sum(case when SRC.QLTY_TEST= 'Fail' then 1 else 0 end) as Fails
from "DV2_OBIADM".IM_LUT_ENTITY_SOFT_RULES EN, SAT_CNTRCT_N4_DQ SRC
WHERE EN.ENTITY_NAME = 'SAT_CNTRCT_N4_DQ'
GROUP BY SRC.SRC_SYS_ID, EN.ENTITY_NAME, EN.SOFT_RULE_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY')))

UNION 

select distinct 
SRC.SRC_SYS_ID,
EN.SOFT_RULE_NAME,
EN.ENTITY_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY'))) as date_,
sum(case when SRC.QLTY_TEST= 'Pass' then 1 else 0 end) as Passes, 
sum(case when SRC.QLTY_TEST= 'Fail' then 1 else 0 end) as Fails
from "DV2_OBIADM".IM_LUT_ENTITY_SOFT_RULES EN, **NEW_SUB_VIEW**SRC
WHERE EN.ENTITY_NAME = '**NEW_SUB_VIEW**'
GROUP BY SRC.SRC_SYS_ID, EN.ENTITY_NAME, EN.SOFT_RULE_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY')))

我希望这很清楚,请帮助我,我在SQL中并不是真正的笨蛋,我不知道该添加触发器还是创建过程!

谢谢!

2 个答案:

答案 0 :(得分:2)

因此,如果我正确理解您的“子视图”中唯一发生变化的部分 是条件

WHERE EN.ENTITY_NAME = '**NEW_SUB_VIEW**'

如果是这样,为什么不将您的“一般视图”实现为

select distinct 
SRC.SRC_SYS_ID,
EN.SOFT_RULE_NAME,
EN.ENTITY_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY'))) as date_,
sum(case when SRC.QLTY_TEST= 'Pass' then 1 else 0 end) as Passes, 
sum(case when SRC.QLTY_TEST= 'Fail' then 1 else 0 end) as Fails
from "DV2_OBIADM".IM_LUT_ENTITY_SOFT_RULES EN, SAT_CNTRCT_N4_DQ SRC
WHERE EN.ENTITY_NAME in (select view_name from my_current_views) 
GROUP BY SRC.SRC_SYS_ID, EN.ENTITY_NAME, EN.SOFT_RULE_NAME,
(to_date(to_char(SRC.LDTS,'DD-MM-YY')))

并维护一个名为 my_current_views

的表
create table my_current_views (
 view_name as varchar2(100)
)

每当要更改“一般视图”时,都将新记录插入my_current_views表中。

答案 1 :(得分:0)

您的要求不是很明确。无论如何,每次将新视图添加到您的架构时,下面的触发器都会自动创建新VIEW。

CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF VARCHAR2(100);

CREATE OR REPLACE TRIGGER T_NEW_VIEW 
    AFTER CREATE ON SCHEMA
    WHEN (ora_dict_obj_type = 'VIEW')
DECLARE 
    sqlcmd CLOB;
    entities VARCHAR_TABLE_TYPE;
BEGIN    

    IF UPPER(ora_dict_obj_name) = 'F_GENERAL_DATA_QLTY' THEN
        -- avoid recursive calling of this trigger!!!
        RETURN;     
    END IF;

    SELECT view_Name
    BULK COLLECT INTO entities 
    FROM NEW_SUB_VIEWS;

    -- "General view" components:
    entities := entities MULTISET UNION DISTINCT VARCHAR_TABLE_TYPE('SAT_CNTRCT_OTH_GCP_DQ', 'SAT_CNTRCT_N4_DQ');

    sqlcmd := 'CREATE OR REPLACE FORCE VIEW DV2_OBIDMT.F_GENERAL_DATA_QLTY '||CHR(13);
    sqlcmd := sqlcmd ||'  (SRC_SYS_ID, SOFT_RULE_NAME, ENTITY_NAME, DATE_, PASSES, FAILS) AS '||CHR(13);
    FOR i IN entities.FIRST..entities.LAST LOOP
        IF i > 1 THEN
            sqlcmd := sqlcmd ||'UNION '||CHR(13);
        END IF;
        sqlcmd := sqlcmd ||'SELECT SRC.SRC_SYS_ID, EN.SOFT_RULE_NAME, EN.ENTITY_NAME, TRUNC(SRC.LDTS) as date_, '||CHR(13)||
            'SUM(CASE WHEN SRC.QLTY_TEST= ''Pass'' THEN 1 ELSE 0 END) as Passes, '||CHR(13)||
            'SUM(CASE WHEN SRC.QLTY_TEST= ''Fail'' THEN 1 ELSE 0 END) as Fails '||CHR(13);
        sqlcmd := sqlcmd || 'FROM DV2_OBIADM.IM_LUT_ENTITY_SOFT_RULES EN '||CHR(13);
        sqlcmd := sqlcmd || '   CROSS JOIN '||entities(i)||' SRC '||CHR(13);
        sqlcmd := sqlcmd || 'WHERE EN.ENTITY_NAME = '''||entities(i)||''''||CHR(13);
        sqlcmd := sqlcmd || 'GROUP BY SRC.SRC_SYS_ID, EN.ENTITY_NAME, EN.SOFT_RULE_NAME, TRUNC(SRC.LDTS) '||CHR(13);
    END LOOP;   
    DBMS_OUTPUT.PUT_LINE(sqlcmd); --> Just to verify and detect errors
    EXECUTE IMMEDIATE sqlcmd;

END;
/

但是,我认为您应该查看整体设计,这可能不是最好的设计。