db2存储过程动态sql被截断

编写存储过程,使用动态sql时,调试时发现变量赋值后被截断。

关键代码如下:

实现的效果是先把上下游做对比的sql语句和相关参数存入RKDM_DATA_VOID_RULE,

执行存储过程后把两个sql语句得出的结果插入另一张结果表RKDM_DATA_VOID_CHK_REST。

建表语句:

CREATE TABLE RKDM_DATA_VOID_CHK_REST (
DATA_DT DATE,
ORDR_NUM INTEGER,
CHK_BIG_CLS VARCHAR(256),
DATA_PRTN VARCHAR(80),
SBJ VARCHAR(256),
ENT_EN VARCHAR(256),
ENT_CN VARCHAR(200),
FLD_EN VARCHAR(100),
FLD_CN VARCHAR(256),
FWD_CHK_SQL VARCHAR(500),
REV_CHK_SQL VARCHAR(500),
CD_TAB VARCHAR(100),
CD_FLD VARCHAR(100),
CHK_AIM VARCHAR(50),
CHK_COMNT VARCHAR(50),
FWD_CHK_RSLT VARCHAR(500),
REV_CHK_RSLT VARCHAR(500),
NULL_CNT INTEGER,
CD_VAL VARCHAR(50),
ERR_CNT INTEGER
)
;

COMMENT ON TABLE RKDM_DATA_VOID_CHK_REST IS ‘数据质量检查结果‘;

COMMENT ON RKDM_DATA_VOID_CHK_REST (
DATA_DT IS ‘数据日期‘,
ORDR_NUM IS ‘序号‘,
CHK_BIG_CLS IS ‘检查类型‘,
DATA_PRTN IS ‘数据分区‘,
SBJ IS ‘主题‘,
ENT_EN IS ‘实体英文名‘,
ENT_CN IS ‘实体中文名‘,
FLD_EN IS ‘字段英文名‘,
FLD_CN IS ‘字段中文名‘,
FWD_CHK_SQL IS ‘上游/正向检查SQL‘,
REV_CHK_SQL IS ‘下游/反向检查SQL‘,
CD_TAB IS ‘代码表‘,
CD_FLD IS ‘代码字段‘,
CHK_AIM IS ‘检查目的‘,
CHK_COMNT IS ‘检查说明‘,
FWD_CHK_RSLT IS ‘上游/正向检查结果‘,
REV_CHK_RSLT IS ‘下游/反向检查结果‘,
NULL_CNT IS ‘空值数‘,
CD_VAL IS ‘代码值‘,
ERR_CNT IS ‘异常条数‘ );

CREATE TABLE RKDM_DATA_VOID_RULE (
ORDR_NUM INTEGER,
CHK_BIG_CLS VARCHAR(256),
DATA_PRTN VARCHAR(80),
SBJ VARCHAR(256),
ENT_EN VARCHAR(256),
ENT_CN VARCHAR(200),
FLD_EN VARCHAR(100),
FLD_CN VARCHAR(256),
FWD_CHK_SQL VARCHAR(500),
REV_CHK_SQL VARCHAR(500),
CD_TAB VARCHAR(100),
CD_FLD VARCHAR(100),
CHK_AIM VARCHAR(500),
CHK_COMNT VARCHAR(500)
)
;

COMMENT ON TABLE RKDM_DATA_VOID_RULE IS ‘数据质量检查规则‘;

COMMENT ON RKDM_DATA_VOID_RULE (
ORDR_NUM IS ‘序号‘,
CHK_BIG_CLS IS ‘检查类型‘,
DATA_PRTN IS ‘数据分区‘,
SBJ IS ‘主题‘,
ENT_EN IS ‘实体英文名‘,
ENT_CN IS ‘实体中文名‘,
FLD_EN IS ‘字段英文名‘,
FLD_CN IS ‘字段中文名‘,
FWD_CHK_SQL IS ‘上游/正向检查SQL‘,
REV_CHK_SQL IS ‘下游/反向检查SQL‘,
CD_TAB IS ‘代码表‘,
CD_FLD IS ‘代码字段‘,
CHK_AIM IS ‘检查目的‘,
CHK_COMNT IS ‘检查说明‘ );

数据:

INSERT INTO RKDM_DATA_VOID_RULE
(Ordr_Num,Chk_Big_Cls,Data_Prtn,Sbj,Ent_EN,Ent_CN,FLD_EN,FLD_CN,Fwd_Chk_SQL,Rev_Chk_SQL,Chk_Aim)
VALUES (‘1‘,
‘关键指标检核_上下游比对‘,
‘零售‘,
‘参与主体‘,
‘TB_RZT_CUST_ACCT_STATS‘,
‘客户账户统计‘,
‘Dmnd_Dpst_Acct_Cnt‘,
‘活期存款账户数‘,
‘SELECT COUNT(1) FROM TEST_T_APP_2 WHERE B=‘‘2‘‘‘,
‘SELECT COUNT(1) FROM TEST_T_APP_3‘,
‘通过对客户账户统计表的活期存款账户数字段源和目标的检核,确认处理逻辑是否存在问题‘);

INSERT INTO RKDM_DATA_VOID_RULE
(Ordr_Num,Chk_Big_Cls,Data_Prtn,Sbj,Ent_EN,Ent_CN,FLD_EN,FLD_CN,Fwd_Chk_SQL,Rev_Chk_SQL,Chk_Aim)
VALUES (‘2‘,
‘关键指标检核_上下游比对‘,
‘零售‘,
‘参与主体‘,
‘TB_RZT_CUST_ACCT_STATS‘,
‘客户账户统计‘,
‘Mtg_Loan_Acct_Cnt‘,
‘按揭贷款账户数‘,
‘SELECT COUNT(1) FROM TEST_T_APP_2 WHERE B=‘‘1‘‘‘,
‘SELECT COUNT(1) FROM TEST_T_APP_3 WHERE B IS NOT NULL‘,
‘通过对客户账户统计表的按揭贷款账户数字段源和目标的检核,确认处理逻辑是否存在问题‘);

存储过程代码:

CREATE OR REPLACE PROCEDURE RKDM_KEY_INDX_CHK(
IN in_data_dt VARCHAR(10),
OUT out_succeed INTEGER
)
DYNAMIC RESULT SETS 1
/******************************************************************************
程序名称:RKDM_KEY_INDX_CHK
功能描述:关键指标测试_上下游比对
输入参数:in_data_dt 数据日期
输出参数:out_succeed 是否成功标志。1-失败 0-成功
作者:
版本号:V1.0.0.0
修改历史:
版本 更改日期 更新人 更新说明

******************************************************************************/
P1:BEGIN
/*************标准定义变量**************************************************/
DECLARE v_job_name VARCHAR(60) DEFAULT ‘CLEAN_DATA‘; --作业名称
DECLARE v_point VARCHAR(10); --记录点
DECLARE v_start_tm TIMESTAMP; --开始执行时间
DECLARE v_end_tm TIMESTAMP; --结束执行时间
DECLARE v_sql VARCHAR(20000); --执行SQL
DECLARE v_ex_sql_log VARCHAR(20000); --执行SQL
DECLARE v_run_result VARCHAR(20); --执行结果
DECLARE v_date VARCHAR(10); --数据日期
DECLARE v_msg VARCHAR(10); --错误信息
DECLARE SQLCODE INT DEFAULT 0; --显示定义数据库变量SQLCODE
DECLARE SQLSTATE CHAR(5) DEFAULT ‘0000‘; --显示定义数据库变量SQLSTATE
DECLARE v_etl_owner VARCHAR(20) DEFAULT ‘ETL‘; --本SP操作的用户

/**************定义常用日期变量**********************************************/
DECLARE V_T_YEAR VARCHAR(4); --本年
DECLARE V_T_MONTH VARCHAR(8); --本月
DECLARE V_T_DAY VARCHAR(8); --本日
DECLARE V_L_YEAR VARCHAR(4); --去年
DECLARE V_F_TX_DATE DATE; --标准日期
DECLARE V_F_C_DATE VARCHAR(10); --十位标准日期字符串格式
DECLARE V_LAST_DAY VARCHAR(8); --上一日
DECLARE V_NEXT_MON_START VARCHAR(8); --下月初
DECLARE V_MON_START VARCHAR(8); --本月初
DECLARE V_MON_END VARCHAR(8); --本月末
DECLARE V_LAST_MON_END VARCHAR(8); --上月末
DECLARE V_BEGIN_YEAR VARCHAR(8); --年初
DECLARE V_LAST_YEAR_END VARCHAR(8); --上年末
DECLARE V_LAST_YEAR_PERIOD VARCHAR(8); --去年同期
DECLARE V_QUARTER VARCHAR(8); --所在季度数 V_QUERTER
DECLARE V_BEGIN_QUARTER VARCHAR(8); --季初
DECLARE V_TH_LAST_MON_END VARCHAR(8); --上上上月末
DECLARE V_TH_LAST_YEAR_END VARCHAR(8); --上上上年末

/**************自定义变量***************************************************/
DECLARE V_DATA_COUNT_PRE INTEGER;
DECLARE DATA_DT VARCHAR(8); --数据日期
DECLARE ETL_DT VARCHAR(8); --ETL处理日期(当前日期)
DECLARE ADD_DT VARCHAR(8); --增量日期
DECLARE MAXDATE VARCHAR(8); --最大日期
DECLARE ILLDATE VARCHAR(8); --错误日期
DECLARE NULLDATE VARCHAR(8); --空日期
DECLARE NULLSTRING VARCHAR(1); --空字符串
DECLARE NULLNUMBER VARCHAR(1); --空数值
DECLARE NULLTIME TIME; --空时间
DECLARE NULLTIMESTAMP TIMESTAMP; --空时间戳

DECLARE v_sql_del VARCHAR(20000); --执行SQL
DECLARE v_sql_fwd VARCHAR(20000); --执行SQL
DECLARE v_sql_rev VARCHAR(20000); --执行SQL
DECLARE v_sql_insert VARCHAR(30000); --执行SQL
DECLARE VAL_FWD VARCHAR(10);
DECLARE VAL_REV VARCHAR(10);
DECLARE RS_STMT_FWD STATEMENT;
DECLARE RS_STMT_REV STATEMENT;
DECLARE RS_C_FWD CURSOR FOR RS_STMT_FWD;
DECLARE RS_C_REV CURSOR FOR RS_STMT_REV;

/**************异常处理******************************************************/
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
GET DIAGNOSTICS EXCEPTION 1 v_msg = MESSAGE_TEXT;
SET out_succeed = 1;
SET v_run_result = ‘执行失败‘;
SET v_msg = ‘SQLCODE:‘||rtrim(CHAR(SQLCODE))||‘.SQLSTATE:‘||SQLSTATE||‘‘||v_msg;
SET v_end_tm = current timestamp;
ROLLBACK;
END;

/**************标准变量处理**************************************************/
SET v_start_tm = current timestamp;
SET v_date = in_data_dt;
SET out_succeed = 0;
SET v_run_result = ‘执行成功‘;
SET v_job_name = ‘CLEAN_DATA‘;

--自定义参数赋值
VALUES in_data_dt INTO DATA_DT;
VALUES to_char(current date,‘YYYYMMDD‘) INTO ETL_DT;
VALUES in_data_dt INTO ADD_DT;
VALUES ‘89991231‘ INTO MAXDATE;
VALUES ‘00010102‘ INTO ILLDATE;
VALUES ‘00010101‘ INTO NULLDATE;
VALUES ‘‘ INTO NULLSTRING;
VALUES 0 INTO NULLNUMBER;
VALUES ‘00:00:00‘ INTO NULLTIME;
VALUES ‘0001-01-01 00:00:00.000000‘ INTO NULLTIMESTAMP;

--自定义日期参数赋值
VALUES substr(in_data_dt,1,4) INTO V_T_YEAR; --本年
VALUES substr(in_data_dt,5,2) INTO V_T_MONTH; --本月
VALUES substr(in_data_dt,7,2) INTO V_T_DAY; --本日
VALUES substr(in_data_dt,1,4)-1 INTO V_L_YEAR; --去年
VALUES to_date(in_data_dt,‘yyyy-mm-dd‘) INTO V_F_TX_DATE; --标准日期
VALUES to_char(to_date(in_data_dt,‘yyyy-mm-dd‘),‘yyyy-mm-dd‘) INTO V_F_C_DATE; --十位标准日期字符串格式
VALUES to_char(to_date(in_data_dt,‘yyyymmdd‘)-1 day,‘yyyymmdd‘) INTO V_LAST_DAY; --上一日
--VALUES to_char(last_day(to_date(in_data_dt,‘yyyymmdd‘))+1 day,‘yyyymmdd‘) INTO V_NEXT_MON_START; --下月初
VALUES V_T_YEAR||V_T_MONTH||‘01‘ INTO V_MON_START; --本月初
--VALUES to_char(last_day(to_date(in_data_dt,‘yyyymmdd‘),‘yyyymmdd‘),‘yyyymmdd‘) INTO V_MON_END; --本月末
VALUES to_char(to_date(V_MON_START,‘yyyymmdd‘)-1 day,‘yyyymmdd‘) INTO V_LAST_MON_END; --上月末
VALUES to_char(to_date(V_T_YEAR||‘-01-01‘,‘yyyymmdd‘),‘yyyymmdd‘) INTO V_BEGIN_YEAR; --年初
VALUES to_char(to_date(V_BEGIN_YEAR,‘yyyymmdd‘)-1 day,‘yyyymmdd‘) INTO V_LAST_YEAR_END; --上年末
VALUES to_char(to_date(in_data_dt,‘yyyymmdd‘)-12 month,‘yyyymmdd‘) INTO V_LAST_YEAR_PERIOD; --去年同期
VALUES CASE WHEN V_T_MONTH IN (‘01‘,‘02‘,‘03‘) THEN ‘1‘
WHEN V_T_MONTH IN (‘04‘,‘05‘,‘06‘) THEN ‘2‘
WHEN V_T_MONTH IN (‘07‘,‘08‘,‘09‘) THEN ‘3‘
WHEN V_T_MONTH IN (‘10‘,‘11‘,‘12‘) THEN ‘4‘
END INTO V_QUARTER; --所在季度
VALUES CASE V_QUARTER
WHEN ‘1‘ THEN V_T_YEAR||‘0101‘
WHEN ‘2‘ THEN V_T_YEAR||‘0401‘
WHEN ‘3‘ THEN V_T_YEAR||‘0701‘
WHEN ‘4‘ THEN V_T_YEAR||‘1001‘
END INTO V_BEGIN_QUARTER; --季初
VALUES to_char(last_day(to_date(in_data_dt,‘yyyymmdd‘)-3 month),‘yyyymmdd‘) INTO V_TH_LAST_MON_END; --上上上月末
VALUES to_char(year(to_date(in_data_dt,‘yyyymmdd‘)-3 year)||‘-01-01‘,‘yyyymmdd‘) INTO V_TH_LAST_YEAR_END; --上上上年末

/**************脚本主要逻辑**************************************************/

--防重跑,先删除数据
SET v_sql_del=‘DELETE FROM RKDM_DATA_VOID_CHK_REST WHERE DATA_DT=‘‘‘||v_date||‘‘‘ AND Chk_Big_Cls=‘‘关键指标检核_上下游比对‘‘‘;
PREPARE DEL_STMT FROM v_sql_del;
EXECUTE DEL_STMT;

--循环检查规则
FOR RS_LOOP AS
SELECT Ordr_Num as Ordr_Num,
Chk_Big_Cls as Chk_Big_Cls,
Data_Prtn as Data_Prtn,
Sbj as Sbj,
Ent_EN as Ent_EN,
Ent_CN as Ent_CN,
FLD_EN as FLD_EN,
FLD_CN as FLD_CN,
Fwd_Chk_SQL as Fwd_Chk_SQL,
Rev_Chk_SQL as Rev_Chk_SQL,
Chk_Aim as Chk_Aim
FROM RKDM_DATA_VOID_RULE WHERE Chk_Big_Cls=‘关键指标检核_上下游比对‘
DO
SET v_sql_fwd=RS_LOOP.Fwd_Chk_SQL;
SET v_sql_rev=RS_LOOP.Rev_Chk_SQL;
PREPARE RS_STMT_FWD FROM v_sql_fwd;
OPEN RS_C_FWD;
PREPARE RS_STMT_REV FROM v_sql_rev;
OPEN RS_C_REV;
FETCH RS_C_FWD INTO VAL_FWD;
FETCH RS_C_REV INTO VAL_REV;
CLOSE RS_C_FWD;
CLOSE RS_C_REV;

SET v_sql_insert=‘INSERT INTO RKDM_DATA_VOID_CHK_REST(DATA_DT,Chk_Big_Cls,Ordr_Num,Data_Prtn,Sbj,Ent_EN,Ent_CN,FLD_EN,FLD_CN,Fwd_Chk_SQL,Rev_Chk_SQL,Fwd_Chk_Rslt,Rev_Chk_Rslt,Chk_Aim)VALUES(‘‘‘||v_date||‘‘‘,‘‘‘||RS_LOOP.Chk_Big_Cls||‘‘‘,‘‘‘||RS_LOOP.Ordr_Num||‘‘‘,‘‘‘||RS_LOOP.Data_Prtn||‘‘‘,‘‘‘||RS_LOOP.Sbj||‘‘‘,‘‘‘||RS_LOOP.Ent_EN||‘‘‘,‘‘‘||RS_LOOP.Ent_CN||‘‘‘,‘‘‘||RS_LOOP.FLD_EN||‘‘‘,‘‘‘||RS_LOOP.FLD_CN||‘‘‘,‘‘‘||RS_LOOP.Fwd_Chk_SQL||‘‘‘,‘‘‘||RS_LOOP.Rev_Chk_SQL||‘‘‘,‘‘‘||VAL_FWD||‘‘‘,‘‘‘||VAL_REV||‘‘‘,‘‘‘||RS_LOOP.Chk_Aim||‘‘‘)‘;
PREPARE RS_STMT_INST FROM v_sql_insert;
EXECUTE RS_STMT_INST;
END FOR;

END P1

问题:使用ibm data studio 调试发现所有的变量都能正常取出来但是整合到v_sql_insert变量中时就会被截断,v_sql_insert这个变量值出来的不是完整的语句。

尝试的方法:1.最后不使用v_sql_insert这个动态sql ,直接这么写:INSERT INTO RKDM_DATA_VOID_CHK_REST(DATA_DT,Chk_Big_Cls,Ordr_Num,Data_Prtn,Sbj,Ent_EN,Ent_CN,FLD_EN,FLD_CN,Fwd_Chk_SQL,Rev_Chk_SQL,Fwd_Chk_Rslt,Rev_Chk_Rslt,Chk_Aim)VALUES(v_date,RS_LOOP.Chk_Big_Cls,RS_LOOP.Ordr_Num,RS_LOOP.Data_Prtn,RS_LOOP.Sbj,RS_LOOP.Ent_EN,RS_LOOP.Ent_CN,RS_LOOP.FLD_EN,RS_LOOP.FLD_CN,RS_LOOP.Fwd_Chk_SQL,RS_LOOP.Rev_Chk_SQL,VAL_FWD,VAL_REV,RS_LOOP.Chk_Aim)这样做是没有问题。

2.建立页比较大的系统临时表空间。

3.修改v_sql_insert这个变量声明的数据类型大小。

时间: 2024-08-25 03:31:10

db2存储过程动态sql被截断的相关文章

SQL Server创建存储过程——动态SQL

简介: 存储过程(stored procedure)是一组为了完成特定功能的SQL语句集合,经编译后存储在服务器端的数据库中,利用存储过程可以加速SQL语句的执行. 自定义存储过程,由用户创建并能完成某一特定功能的存储过程,存储过程既可以有参数又有返回值,但是它与函数不同,存储过程的返回值只是指明执行是否成功, 存储过程并不能像函数那样被直接调用,只能利用 execute 来执行存储过程. 优点: 1.提高应用程序的通用性和可移植性:存储过程创建后,可以在程序中被多次调用,而不必重新编写该存储过

sql server、db2、oracle 存储过程动态sql语句示例

Oracle CREATE OR REPLACE PROCEDURE a_test AS t_sql VARCHAR2(2000); t_a VARCHAR2(20); t_b VARCHAR2(20); t_c VARCHAR2(20); t_d VARCHAR2(20); BEGIN t_c := 'f'; t_d := 'g'; --这里可为insert 等任何sql语句. t_sql := 'SELECT MAX(a), MAX(b) FROM t1 WHERE c = :tempC O

DB2 存储过程中执行动态SQL

样本代码: DROP PROCEDURE QUOTATION.COPY_SAMPLE; CREATE PROCEDURE QUOTATION.COPY_SAMPLE ( IN tableNameFrom VARCHAR(30) , IN tableNameTo VARCHAR(30) , INOUT copyResult INTEGER) BEGIN DECLARE SQLCODE INTEGER DEFAULT 0; SET copyResult = 0; -- Proecss 1 BEGIN

DB2存储过程实现查询表数据,生成动态SQL,并执行

一.动态执行SQL PREPARE S1 FROM 'delete from test'; EXECUTE S1; 二.使用游标 DECLARE V_CURSOR CURSOR FOR SELECT DELETESQL,INSERTSQL FROM FJDC.V_I_DG_DM_ZY_WL_ZBHZ_ATTR T; OPEN V_CURSOR; FETCH V_CURSOR INTO V_DELETESQL,V_INSERTSQL; CLOSE V_CURSOR; 三.WHILE循环 WHILE

存储过程中执行动态Sql语句

存储过程中执行动态Sql语句 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就是利用sp_executesql,能够重用执行计划,这就大大提供了执行性能,还可以编写更安全的代码.EXEC在某些情况下会更灵活.除非您有令人信服的理由使用EXEC,否侧尽量使用sp_executesql. 1.EXEC的使用 EXEC命令有两种用法,一种是执行一个存储

存储过程执行动态sql语句

MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就是利用sp_executesql,能够重用执行计划,这就大大提供了执行性能,还可以编写更安全的代码.EXEC在某些情况下会更灵活.除非您有令人信服的理由使用EXEC,否侧尽量使用sp_executesql. 1.EXEC的使用 EXEC命令有两种用法,一种是执行一个存储过程,另一种是执行一个动态的批

mysql存储过程动态执行SQL

CREATE PROCEDURE feeMonth(in fmark varchar(200),in fuser char(32),in ftime BIGINT,in fmonth char(6)) BEGIN #定义SQL变量 declare create_sql varchar(100); declare sel_sql varchar(100); declare del_sql varchar(100); declare fmon varchar(100); #定义表名变量 declar

在存储过程中用动态SQL建表后如果用PL/SQL插入

请教各位老师一个问题,如果想把一个表的建立并插入数据放到一个存储过程中,应该要怎么处理呢,如果插入数据的表在存过中插入数据之前未建立,存储过程会报错提示表不存在,导致存储过程失效,有没有什么变通的办法呢? 之所以不在存储过程之外建表是想定时执行这个存储过程,如果存在表被DROP的情况,就会导致存储过程插入数据报错了,所以想在存储过程中自动把表的建立和处理一起考虑了,插入数据不考虑使用动态SQL来插入,因为这样的话就不能使用plsql的东西了(比如远程链接优化的提示),请教怎么处理,谢谢啦! 简单

怎样SQL存储过程中执行动态SQL语句

MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就是利用sp_executesql,能够重用执行计划,这就大大提供了执行性能,还可以编写更安全的代码.EXEC在某些情况下会更灵活.除非您有令人信服的理由使用EXEC,否侧尽量使用sp_executesql.1.EXEC的使用 EXEC命令有两种用法,一种是执行一个存储过程,另一种是执行一个动态的批处