存储过程-根据类型合并相邻的票据

--drop table test;

-- 保存缓存数据的表
create table test (
ftype varchar(32) ,
fstart_serial integer ,
fstart_code varchar(18) ,
fend_serial integer ,
fend_code varchar(18)
)

-- 测试数据
select * from table( values('1001', 3, '001', 1), ('1001', 3, '002', 2), ('1001', 3, '010', 10), ('1001', 3, '011', 11),
('1002', 5, '00001', 1), ('1002', 5, '00002', 2), ('1002', 5, '00010', 10), ('1002', 5, '00011', 11)

) as t(ftype, flen, fcode, fserial)
order by ftype, fserial


-- 创建一个临时表用来保存计算后的数据
DECLARE GLOBAL TEMPORARY TABLE session.test (
ftype varchar(32) ,
flen integer ,
fstart_serial integer ,
fstart_code varchar(18) ,
fend_serial integer ,
fend_code varchar(18)
)
NOT LOGGED WITH REPLACE;

-- 删除存储过程
--drop PROCEDURE PROC_TEST;

-- 创建存储过程
-- 根据类型合并相邻的票据:先将合并后的票据保存到临时表然后再保存
CREATE PROCEDURE PROC_TEST (
IN "PARA_ISSAVE" INTEGER, -- 是否保存数据
IN "PARA_ISREFRESH" INTEGER -- 是否刷新数据
)
DYNAMIC RESULT SETS 1
LANGUAGE SQL
NOT DETERMINISTIC
CALLED ON NULL INPUT
EXTERNAL ACTION
OLD SAVEPOINT LEVEL
MODIFIES SQL DATA
INHERIT SPECIAL REGISTERS

proc_test_:

BEGIN NOT ATOMIC

-- 保存查询数据的变量
DECLARE type_ varchar(32);
DECLARE len_ integer;
DECLARE serial_ integer;
DECLARE code_ varchar(18);

-- 保存合并后的数据变量
DECLARE endType varchar(32);
DECLARE startSerial integer;
DECLARE startCode varchar(18);
DECLARE endSerial integer;
DECLARE endCode varchar(18);

-- 缓存表的记录数
declare count integer;

-- 执行sql是否出错的标记
declare sqlcode INT DEFAULT 0;

-- 0 取缓存(查询缓存表的数据)
DECLARE c_ret0 CURSOR with return FOR select ftype, fstart_serial, fstart_code, fend_serial, fend_code from test;

-- 1 刷新查询
DECLARE c_ret1 CURSOR with return FOR select ftype, fstart_serial, fstart_code, fend_serial, fend_code from session.test ;

--获取原始数据
DECLARE c_test CURSOR FOR
select ftype, flen, fcode, fserial from table( values('1001', 3, '001', 1), ('1001', 3, '002', 2), ('1001', 3, '010', 10), ('1001', 3, '011', 11),
('1002', 5, '00001', 1), ('1002', 5, '00002', 2), ('1002', 5, '00010', 10), ('1002', 5, '00011', 11)

) as t(ftype, flen, fcode, fserial)
order by ftype,fserial;

-- 创建一个临时表用来保存计算后的数据
DECLARE GLOBAL TEMPORARY TABLE session.test (
ftype varchar(32) ,
flen integer ,
fstart_serial integer ,
fstart_code varchar(18) ,
fend_serial integer ,
fend_code varchar(18)
)
NOT LOGGED WITH REPLACE;

if PARA_ISREFRESH = 0 then -- 不刷新时还要判断是否有缓存数据
select count(*) into count from test;
end if;

if PARA_ISREFRESH = 1 or count = 0 then -- 如果需要刷新数据或者没有缓存数据

open c_test ;

FETCH c_test INTO type_, len_, code_, serial_ ;

--------根据类型合并编号-------------------------------------------------------
if sqlcode = 0 then
set startSerial = serial_;
set endSerial = serial_ - 1;
set endType = type_;
WHILE sqlcode = 0 DO
if endType <> type_ or endSerial + 1 <> serial_ then -- 类型不相同或者号码不连续
insert into session.test (ftype, flen, fstart_serial, fend_serial) values (endType, len_, startSerial, endSerial);
set startSerial = serial_;
end if;

set endSerial = serial_;
set endType = type_;
FETCH c_test INTO type_, len_, code_, serial_ ;
END WHILE ;

CLOSE c_test;

--保存最后一条记录
insert into session.test (ftype, flen, fstart_serial, fend_serial) values (endType, len_, startSerial, endSerial);

--写编号, 不够长度的补0
update session.test set fstart_code = REPEAT( '0', flen - length(rtrim(cast( fstart_serial as char(18) ))) ) || rtrim(cast( fstart_serial as char(18) )) ,
fend_code = REPEAT( '0', flen - length(rtrim(cast( fend_serial as char(18) ))) ) || rtrim(cast( fend_serial as char(18) )) ;

end if;
----------合并结束-------------------------------------------------------------

--保存查询结果
if PARA_ISSAVE =1 then
delete from test;
insert into test (ftype, fstart_serial, fstart_code, fend_serial, fend_code)
select ftype, fstart_serial, fstart_code, fend_serial, fend_code from session.test;
end if;

end if;


if PARA_ISREFRESH = 1 then
open c_ret1; -- 1 刷新查询
else
open c_ret0; -- 0 取缓冲
end if;

end proc_test_;


--调用存储过程
call PROC_TEST(1, 1);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值