自动生成存储过程抽取数据

在工作中我们常常需要从各种业务系统抽取数据到自己的数据库做各种处理与计算,做数据挖掘与分析等等,但是抽取过程中,insert()后面我们最好是需要指定具体的字段的,不然的话原库数据库表结构一变我们就凉凉,要么就是直接报错,要么就是抽取的数据和字段不对应等问题,但是执行字段的话又需要我们去复制字段,非常繁琐。

在此背景下,我们开发一个自动生成的存储过程,自动获取表的字段,并且拼接insert(字段)select(字段)信息,并将监控信息插入,然后一编译即可,方法如下:

1、首先我们先建一个日志表如下:

-- Create table
create table PUB_LOG
(
  V_DATE          VARCHAR2(20),
  V_PROC_NAME     VARCHAR2(50),
  V_AR_NAME       VARCHAR2(30),
  V_BEGINTIME     TIMESTAMP(6),
  V_RUN_LONG      VARCHAR2(50),
  V_SQLCODE       VARCHAR2(30),
  V_ERROR_MESSAGE VARCHAR2(500),
  V_EXCUMESS      VARCHAR2(1000),
  V_DIRTABLE      VARCHAR2(60),
  V_COUNT         VARCHAR2(30),
  V_ENDTIME       TIMESTAMP(6)
)
tablespace BIGDATA_STG
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 256
    next 8
    minextents 1
    maxextents unlimited
    pctincrease 0
  );
-- Add comments to the table 
comment on table PUB_LOG
  is '日志表';
-- Add comments to the columns 
comment on column PUB_LOG.V_DATE
  is '执行日期';
comment on column PUB_LOG.V_PROC_NAME
  is '存储过程名称';
comment on column PUB_LOG.V_AR_NAME
  is '模块名称';
comment on column PUB_LOG.V_BEGINTIME
  is '开始时间';
comment on column PUB_LOG.V_RUN_LONG
  is '运行时长';
comment on column PUB_LOG.V_SQLCODE
  is '消息编码';
comment on column PUB_LOG.V_ERROR_MESSAGE
  is '消息内容';
comment on column PUB_LOG.V_EXCUMESS
  is '操作说明';
comment on column PUB_LOG.V_DIRTABLE
  is '操作表';
comment on column PUB_LOG.V_COUNT
  is '影响行数';
comment on column PUB_LOG.V_ENDTIME
  is '结束时间';
-- Grant/Revoke object privileges 
grant select on PUB_LOG to DM;
grant select on PUB_LOG to DW;

2、创建添加日志的存储过程

建了存储过程以后,在添加日志监控的时候,调用这个日志就行,就不用每次都去写insert了

存储过程如下:

create or replace procedure PORC_INSERT_LOG(
                                 ETL_DATE    VARCHAR,
                                 PROC_NAME   VARCHAR,
                                 AR_NAME     VARCHAR,
                                 BEGIN_TIME    TIMESTAMP,
                                 RUN_LONG    VARCHAR,
                                 MS_CODE     VARCHAR,
                                 MS_CONTECT  VARCHAR,
                                 SQL_CONTECT VARCHAR,
                                 SQL_TABLE   VARCHAR,
                                 SQL_COUNT   INTEGER,
                                 END_TIME    TIMESTAMP) is
begin

INSERT INTO PUB_LOG (
                                 V_DATE    ,
                                 V_PROC_NAME   ,
                                 V_AR_NAME     ,
                                 V_BEGINTIME    ,
                                 V_RUN_LONG    ,
                                 V_SQLCODE     ,
                                 V_ERROR_MESSAGE  ,
                                 V_EXCUMESS ,
                                 V_DIRTABLE   ,
                                 V_COUNT   ,
                                 V_ENDTIME    

)
VALUES (
                                 ETL_DATE    ,
                                 PROC_NAME   ,
                                 AR_NAME     ,
                                 BEGIN_TIME    ,
                                 RUN_LONG    ,
                                 MS_CODE     ,
                                 MS_CONTECT  ,
                                 SQL_CONTECT ,
                                 SQL_TABLE   ,
                                 SQL_COUNT   ,
                                 END_TIME    
);

COMMIT;

end PORC_INSERT_LOG;

3、本人存储过程模板如下:

create or replace procedure STG_TECHNICALAGREEMENT is

  V_ERROR_MESSAGE VARCHAR2(255); --SQL运行信息
  V_SQLCODE       VARCHAR2(100); --SQL运行编码
  V_SQL           CLOB; --SQL
  V_EXCUMESS      VARCHAR2(500); --操作说明
  V_PROC_NAME     VARCHAR2(50); --存储过程名
  V_AR_NAME       VARCHAR2(50); --存储过程的第几部分,修改模板名称 标志程序日志的精确位置
  V_BEGINTIME     TIMESTAMP; --开始时间
  V_ENDTIME       TIMESTAMP; --结束时间
  V_RUN_LONG      VARCHAR2(100); --运行时长
  V_COUNT         INTEGER; --程序影响行数
  V_DIRTABLE      VARCHAR2(100); --执行ETL的目标表名
  V_DATE          VARCHAR2(50); --ETL日期
  --V_SYSTIME       TIMESTAMP; --系统时间
  --V_PERIOD        VARCHAR2(50); --ETL时间
begin
  /*======================================================================
   *
   * 模板名称:技术协议STG层数据抽取
   * 过程名称:STG_TECHNICALAGREEMENT
   * 参    数:
   * 功能描述:技术协议STG层数据抽取
   * 程序结构:
   *           PART1   STG_MES_CHECK_RWSINTERFACE     送筛单
   *           PART2   STG_MES_COMPANYCOST            委托单位收费标准
   *           PART3   STG_MES_COMPANYCOST_B          委托单位收费标准子表
   *           PART4   STG_MES_COSTSTANDARD           费用标准
   *           PART5   STG_MES_DPARESULT              DPA结论库
   * 依赖过程:
   * 后续过程:
   * 仓库  层:STG
   * 目标  表:
   * 版本历史:V1.0
   * 开发  者:[email protected] 用友开发组
   * 
  ======================================================================*/

  V_PROC_NAME := 'STG_TECHNICALAGREEMENT'; /*修改过程名*/
  --V_PERIOD    := SUBSTR(SYSDATE, 1, 7);

  /**************************** PART1 STG_MES_CHECK_RWSINTERFACE 送筛单 数据清除与重新插入 ****************************/
  BEGIN
    /* PART1 */
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE; /*运行开始日期*/
    V_AR_NAME   := 'PART1_1'; /*修改模板名称 标志程序日志的精确位置*/
    V_DIRTABLE  := 'STG_MES_CHECK_RWSINTERFACE';
    V_SQL       := 'TRUNCATE TABLE ' || V_DIRTABLE;
    EXECUTE IMMEDIATE V_SQL;
    V_COUNT         := SQL%ROWCOUNT; /*程序影响行数*/
    V_EXCUMESS      := '清除 STG_MES_CHECK_RWSINTERFACE 技术协议_送筛单 的数据';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME; /*运行时长*/
    V_SQLCODE       := SQLCODE; /*运行错误编码*/
    V_ERROR_MESSAGE := SQLERRM; /*SQL 运行消息,写入正常日志*/
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);
  END PART1_1;
  COMMIT;

  BEGIN
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE;
    V_AR_NAME   := 'PART1_2';
    INSERT INTO STG_MES_CHECK_RWSINTERFACE SELECT * FROM MES_CHECK_RWSINTERFACE@NC;
    V_COUNT         := SQL%ROWCOUNT;
    V_EXCUMESS      := 'STG_MES_CHECK_RWSINTERFACE 技术协议_送筛单 数据插入';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME;
    V_SQLCODE       := SQLCODE;
    V_ERROR_MESSAGE := SQLERRM;
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART1_2;
  COMMIT;

  /**************************** PART2 STG_MES_COMPANYCOST 委托单位收费标准 数据清除与重新插入 ****************************/
  BEGIN
    /* PART2 */
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE; /*运行开始日期*/
    V_AR_NAME   := 'PART2_1'; /*修改模板名称 标志程序日志的精确位置*/
    V_DIRTABLE  := 'STG_MES_COMPANYCOST';
    V_SQL       := 'TRUNCATE TABLE ' || V_DIRTABLE;
    EXECUTE IMMEDIATE V_SQL;
    V_COUNT         := SQL%ROWCOUNT; /*程序影响行数*/
    V_EXCUMESS      := '清除 STG_MES_COMPANYCOST 委托单位收费标准 的数据';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME; /*运行时长*/
    V_SQLCODE       := SQLCODE; /*运行错误编码*/
    V_ERROR_MESSAGE := SQLERRM; /*SQL 运行消息,写入正常日志*/
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART2_1;
  COMMIT;

  BEGIN
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE;
    V_AR_NAME   := 'PART2_2';
    INSERT INTO STG_MES_COMPANYCOST SELECT * FROM MES_COMPANYCOST@NC;
    V_COUNT         := SQL%ROWCOUNT;
    V_EXCUMESS      := 'STG_MES_COMPANYCOST 委托单位收费标准 数据插入';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME;
    V_SQLCODE       := SQLCODE;
    V_ERROR_MESSAGE := SQLERRM;
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART2_2;
  COMMIT;

  /**************************** PART3 STG_MES_COMPANYCOST_B 委托单位收费标准子表 数据清除与重新插入 ****************************/
  BEGIN
    /* PART3 */
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE; /*运行开始日期*/
    V_AR_NAME   := 'PART3_1'; /*修改模板名称 标志程序日志的精确位置*/
    V_DIRTABLE  := 'STG_MES_COMPANYCOST_B';
    V_SQL       := 'TRUNCATE TABLE ' || V_DIRTABLE;
    EXECUTE IMMEDIATE V_SQL;
    V_COUNT         := SQL%ROWCOUNT; /*程序影响行数*/
    V_EXCUMESS      := '清除 STG_MES_COMPANYCOST_B 委托单位收费标准子表 的数据';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME; /*运行时长*/
    V_SQLCODE       := SQLCODE; /*运行错误编码*/
    V_ERROR_MESSAGE := SQLERRM; /*SQL 运行消息,写入正常日志*/
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART3_1;
  COMMIT;

  BEGIN
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE;
    V_AR_NAME   := 'PART3_2';
    INSERT INTO STG_MES_COMPANYCOST_B SELECT * FROM MES_COMPANYCOST_B@NC;
    V_COUNT         := SQL%ROWCOUNT;
    V_EXCUMESS      := 'STG_MES_COMPANYCOST_B 委托单位收费标准子表 值数据插入';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME;
    V_SQLCODE       := SQLCODE;
    V_ERROR_MESSAGE := SQLERRM;
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART3_2;
  COMMIT;

  /**************************** PART4 STG_MES_COSTSTANDARD 费用标准 数据清除与重新插入 ****************************/
  BEGIN
    /* PART4 */
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE; /*运行开始日期*/
    V_AR_NAME   := 'PART4_1'; /*修改模板名称 标志程序日志的精确位置*/
    V_DIRTABLE  := 'STG_MES_COSTSTANDARD';
    V_SQL       := 'TRUNCATE TABLE ' || V_DIRTABLE;
    EXECUTE IMMEDIATE V_SQL;
    V_COUNT         := SQL%ROWCOUNT; /*程序影响行数*/
    V_EXCUMESS      := '清除 STG_MES_COSTSTANDARD 费用标准 的数据';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME; /*运行时长*/
    V_SQLCODE       := SQLCODE; /*运行错误编码*/
    V_ERROR_MESSAGE := SQLERRM; /*SQL 运行消息,写入正常日志*/
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART4_1;
  COMMIT;

  BEGIN
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE;
    V_AR_NAME   := 'PART4_2';
    INSERT INTO STG_MES_COSTSTANDARD SELECT * FROM MES_COSTSTANDARD@NC;
    V_COUNT         := SQL%ROWCOUNT;
    V_EXCUMESS      := 'STG_MES_COSTSTANDARD 费用标准 数据插入';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME;
    V_SQLCODE       := SQLCODE;
    V_ERROR_MESSAGE := SQLERRM;
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART4_2;
  COMMIT;


  /**************************** PART5 STG_MES_DPARESULT DPA结论库 数据清除与重新插入 ****************************/
  BEGIN
    /* PART5 */
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE; /*运行开始日期*/
    V_AR_NAME   := 'PART5_1'; /*修改模板名称 标志程序日志的精确位置*/
    V_DIRTABLE  := 'STG_MES_DPARESULT';
    V_SQL       := 'TRUNCATE TABLE ' || V_DIRTABLE;
    EXECUTE IMMEDIATE V_SQL;
    V_COUNT         := SQL%ROWCOUNT; /*程序影响行数*/
    V_EXCUMESS      := '清除 STG_MES_DPARESULT DPA结论库 的数据';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME; /*运行时长*/
    V_SQLCODE       := SQLCODE; /*运行错误编码*/
    V_ERROR_MESSAGE := SQLERRM; /*SQL 运行消息,写入正常日志*/
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART4_1;
  COMMIT;

  BEGIN
    V_DATE      := TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS');
    V_BEGINTIME := SYSDATE;
    V_AR_NAME   := 'PART5_2';
    INSERT INTO STG_MES_DPARESULT SELECT * FROM MES_DPARESULT@NC;
    V_COUNT         := SQL%ROWCOUNT;
    V_EXCUMESS      := 'STG_MES_DPARESULT DPA结论库 数据插入';
    V_ENDTIME       := SYSDATE;
    V_RUN_LONG      := V_ENDTIME - V_BEGINTIME;
    V_SQLCODE       := SQLCODE;
    V_ERROR_MESSAGE := SQLERRM;
    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);

  END PART5_2;
  COMMIT;

end STG_TECHNICALAGREEMENT;

如上存储过程中,每一个part的第一部分是清空表,第二部分是插入数据。

4、字段生成存储过程的脚本

思路:将字段利用 xmlagg xmlparse content 等函数拼接到一起,然后拼上其他监控信息即可

--A将某一个表的所有字段拼接到一起,并有序号和表英文名
with A as (
select  rank() over(order by a.table_name) rowno,a.table_name,xmlagg(xmlparse(content a.column_name||',')order by a.table_name).getclobval() as columns_name 
from user_tab_columns a
where a.table_name like 'STG_DEMES_%'
group by table_name
),
--B加入表注释
B as (
select a.rowno,a.table_name,b.comments as table_comments,a.columns_name
from A a
left join user_tab_comments b on a.table_name = b.table_name
order by a.rowno
),
--C拼接出单个表的存储过程
C as (
select
B.rowno,
B.table_name,
'/**************************** PART_'|| B.rowno || ' ' || B.table_name || ' ' || B.table_comments || ' 数据清除与重新插入 ****************************/'
|| chr(13) || chr(10) || 'BEGIN' 
|| chr(13) || chr(10) || '    V_DATE            := TO_CHAR(SYSDATE,' || '''YYYY-MM-DD HH24:MI:SS'''||');'
|| chr(13) || chr(10) || '    V_BEGINTIME       := SYSDATE; /*运行开始日期*/'
|| chr(13) || chr(10) || '    V_AR_NAME         := ' || '''PART_' ||  B.rowno || '''; /*修改模板名称 标志程序日志的精确位置*/'
|| chr(13) || chr(10) || '    V_DIRTABLE        :=  ''' || B.table_name ||  ''';'
|| chr(13) || chr(10) || '    V_SQL             := ' || '''TRUNCATE  TABLE '''  || ' || V_DIRTABLE ;'
|| chr(13) || chr(10) || '    EXECUTE IMMEDIATE V_SQL;'
|| chr(13) || chr(10) || '    V_COUNT           := SQL%ROWCOUNT; /*程序影响行数*/'
|| chr(13) || chr(10) || '    V_EXCUMESS        := ''' || '清除 '  || B.table_name || '  ' || B.table_comments ||  ' 的数据' || ''';'
|| chr(13) || chr(10) || '    V_ENDTIME         := SYSDATE;'
|| chr(13) || chr(10) || '    V_RUN_LONG        := V_ENDTIME - V_BEGINTIME; /*运行时长*/'
|| chr(13) || chr(10) || '    V_SQLCODE         := SQLCODE; /*运行错误编码*/'
|| chr(13) || chr(10) || '    V_ERROR_MESSAGE   := SQLERRM; /*SQL 运行消息,写入正常日志*/'
|| chr(13) || chr(10) || '    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);'
|| chr(13) || chr(10) || 'END;' 
|| chr(13) || chr(10) || 'COMMIT;' 
|| chr(13) || chr(10)
|| chr(13) || chr(10)
|| chr(13) || chr(10) || 'BEGIN' 
|| chr(13) || chr(10) || '    V_DATE            := TO_CHAR(SYSDATE,' || '''YYYY-MM-DD HH24:MI:SS'''||');'
|| chr(13) || chr(10) || '    V_BEGINTIME       := SYSDATE; /*运行开始日期*/'
|| chr(13) || chr(10) || '    V_AR_NAME         := ' || '''PART_' ||  B.rowno || '''; /*修改模板名称 标志程序日志的精确位置*/'
|| chr(13) || chr(10) || '    insert into ' || lower(B.table_name) || '(' || lower(substr(B.columns_name,1,length(B.columns_name)-1)) || ')' 
|| chr(13) || chr(10) || '    select ' || lower(substr(B.columns_name,1,length(B.columns_name)-1)) || chr(13) || chr(10) || '    from ' || lower(replace (B.table_name,'STG_DEMES_','')) || '@DE_MES ;'
|| chr(13) || chr(10) || '    V_COUNT           := SQL%ROWCOUNT; /*程序影响行数*/'
|| chr(13) || chr(10) || '    V_EXCUMESS        := ''' || B.table_name || ' ' || B.table_comments ||  '数据插入''' || ';'
|| chr(13) || chr(10) || '    V_ENDTIME         := SYSDATE;'
|| chr(13) || chr(10) || '    V_RUN_LONG        := V_ENDTIME - V_BEGINTIME; /*运行时长*/'
|| chr(13) || chr(10) || '    V_SQLCODE         := SQLCODE; /*运行错误编码*/'
|| chr(13) || chr(10) || '    V_ERROR_MESSAGE   := SQLERRM; /*SQL 运行消息,写入正常日志*/'
|| chr(13) || chr(10) || '    PORC_INSERT_LOG(V_DATE,V_PROC_NAME,V_AR_NAME,V_BEGINTIME,V_RUN_LONG,V_SQLCODE,V_ERROR_MESSAGE,V_EXCUMESS,V_DIRTABLE,V_COUNT,V_ENDTIME);'
|| chr(13) || chr(10) || 'END;' 
|| chr(13) || chr(10) || 'COMMIT;'  as col_c
from B
),
--D将所有表的存储过程拼接到一起
D as (
select xmlagg(xmlparse(content C.col_c|| (chr(13) || chr(10) || chr(13) || chr(10)))order by C.table_name).getclobval() as col_d from C
),
--E拼接存储过程表头
E as (
select
'create or replace procedure !!! is'
|| chr(13) || chr(10) 
|| chr(13) || chr(10) || '  V_ERROR_MESSAGE VARCHAR2(255); --SQL运行信息'
|| chr(13) || chr(10) || '  V_SQLCODE       VARCHAR2(100); --SQL运行编码'
|| chr(13) || chr(10) || '  V_SQL           CLOB; --SQL'
|| chr(13) || chr(10) || '  V_EXCUMESS      VARCHAR2(500); --操作说明'
|| chr(13) || chr(10) || '  V_PROC_NAME     VARCHAR2(50); --存储过程名'
|| chr(13) || chr(10) || '  V_AR_NAME       VARCHAR2(50); --存储过程的第几部分,修改模板名称 标志程序日志的精确位置'
|| chr(13) || chr(10) || '  V_BEGINTIME     TIMESTAMP; --开始时间'
|| chr(13) || chr(10) || '  V_ENDTIME       TIMESTAMP; --结束时间'
|| chr(13) || chr(10) || '  V_RUN_LONG      VARCHAR2(100); --运行时长'
|| chr(13) || chr(10) || '  V_COUNT         INTEGER; --程序影响行数'
|| chr(13) || chr(10) || '  V_DIRTABLE      VARCHAR2(100); --执行ETL的目标表名'
|| chr(13) || chr(10) || '  V_DATE          VARCHAR2(50); --ETL日期'
|| chr(13) || chr(10) || '  --V_SYSTIME       TIMESTAMP; --系统时间'
|| chr(13) || chr(10) || '  --V_PERIOD        VARCHAR2(50); --ETL时间'
|| chr(13) || chr(10) || 'begin'
|| chr(13) || chr(10) || '  /*======================================================================'
|| chr(13) || chr(10) || '   *'
|| chr(13) || chr(10) || '   * 模板名称:技术协议STG层数据抽取'
|| chr(13) || chr(10) || '   * 过程名称:!!!'
|| chr(13) || chr(10) || '   * 参    数:'
|| chr(13) || chr(10) || '   * 功能描述:技术协议STG层数据抽取'
|| chr(13) || chr(10) || '   * 程序结构:'
as col_e from dual),
--F拼接存储过程目录
F as (
select b.rowno,
chr(13) || chr(10) || '   *           PART' || b.rowno || '   ' || b.table_name || '   ' || b.table_comments
as col_f from b
),
--G拼接存储过程后半部分
G as (
select
   chr(13) || chr(10) || '   * 依赖过程:'
|| chr(13) || chr(10) || '   * 后续过程:'
|| chr(13) || chr(10) || '   * 仓库  层:STG'
|| chr(13) || chr(10) || '   * 目标  表:'
|| chr(13) || chr(10) || '   * 版本历史:V1.0'
|| chr(13) || chr(10) || '   * '
|| chr(13) || chr(10) || '  ======================================================================*/'
|| chr(13) || chr(10)
|| chr(13) || chr(10) || '  V_PROC_NAME := ''!!!''; /*修改过程名*/'
|| chr(13) || chr(10) || '  --V_PERIOD    := SUBSTR(SYSDATE, 1, 7);'
|| chr(13) || chr(10) || chr(13) || chr(10) 
as col_g from dual
),
I as (
select E.col_e,xmlagg(xmlparse(content F.col_f|| '')order by F.rowno).getclobval() as col_i,col_g from E,F,G
)

select concat(concat(concat(concat(I.col_e,I.col_i),I.col_g),D.col_d),'end !!!;') from I,D

生成的存储过程如下所示:

ps:截图只截了其中一个,可以生成N个,在脚本最开始的地方可以对要生成的表做过滤

希望有所帮到您,如果您有更好的方法,也可以共享一下。

猜你喜欢

转载自blog.csdn.net/weixin_35353187/article/details/107769597