在工作中我们常常需要从各种业务系统抽取数据到自己的数据库做各种处理与计算,做数据挖掘与分析等等,但是抽取过程中,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
* 开发 者:zhangjj7@yonyou.com 用友开发组
*
======================================================================*/
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个,在脚本最开始的地方可以对要生成的表做过滤
希望有所帮到您,如果您有更好的方法,也可以共享一下。