--存储过程包
CREATE OR REPLACE PACKAGE Pkg_Deal_Data AS
-- Author : liuchj@sunline.cn
-- Created : 2016/4/1 21:07:57
-- Purpose : 会计流水数据整理
PROCEDURE Com_Main(Pi_Pckgdt IN VARCHAR2); --报文
END Pkg_Deal_Data;
CREATE OR REPLACE PACKAGE BODY Pkg_Deal_Data IS
PROCEDURE Deal_Data(Pi_Pckgdt IN VARCHAR2 --传入报文参数
) IS
i_Count INT;
BEGIN
--请将如下语句替换为生成gli_vchr的代码
i_Count := 1;
--//结束
END Deal_Data;
PROCEDURE Deal_Succ(Pi_Pckgdt IN VARCHAR2) IS --传入报文参数
BEGIN
UPDATE Glo_Imdt g SET g.Status = '5' WHERE g.Bathid = pkg_pub.get_pkgstr('batchid', Pi_Pckgdt)
AND stacid = pkg_pub.get_pkgstr('user_stacid', Pi_Pckgdt) AND plancd = pkg_pub.get_pkgstr('plancd', Pi_Pckgdt);
commit;
END Deal_Succ;
PROCEDURE Deal_Error(Pi_Pckgdt IN VARCHAR2 --传入报文参数
) IS
BEGIN
UPDATE Glo_Imdt g SET g.Status = '6' WHERE g.Bathid = pkg_pub.get_pkgstr('batchid', Pi_Pckgdt)
AND stacid = pkg_pub.get_pkgstr('user_stacid', Pi_Pckgdt) AND plancd = pkg_pub.get_pkgstr('plancd', Pi_Pckgdt);
commit;
END Deal_Error;
PROCEDURE Com_Main(Pi_Pckgdt IN VARCHAR2 --传入报文参数
) IS
BEGIN
Deal_Data(Pi_Pckgdt);
Deal_Succ(Pi_Pckgdt);
EXCEPTION
WHEN OTHERS THEN
Deal_Error(Pi_Pckgdt);
END Com_Main;
END Pkg_Deal_Data;
--函数包
CREATE OR REPLACE PACKAGE Pkg_Pub IS
FUNCTION Get_Pkgstr(Pi_Fildna IN VARCHAR2, --字段名称
Pi_Pkgstr IN VARCHAR2) --报文字符串
RETURN VARCHAR2; --字段对应的值(如果是循环字段则返回第一个字段的值)
END Pkg_Pub;
CREATE OR REPLACE PACKAGE BODY Pkg_Pub IS
c_Trans_Char CONSTANT VARCHAR2(1) := '\'; --转义字符
c_Level_Delimiter CONSTANT VARCHAR2(1) := ':'; --层次分隔符
c_Name_Value_Delimiter CONSTANT VARCHAR2(1) := '='; --字段值分隔符
c_Field_Delimiter CONSTANT VARCHAR2(1) := '|'; --字段分隔符
/**
取得字段值的位置:
如果是在第一个,不需要匹配'|'
1、找出filed字段的起始值,必须是该字段前后为空、或者前后都必须为4个特殊字符,方能匹配
*/
FUNCTION Field_Pos(Pi_Source VARCHAR2,
Pi_Param VARCHAR2) RETURN INT IS
l_Lipos PLS_INTEGER; --字段结束位置
l_Length PLS_INTEGER;
l_Bgchar VARCHAR2(20);
l_Edchar VARCHAR2(20);
BEGIN
BEGIN
l_Length := Length(Pi_Source);
l_Lipos := Instr(Pi_Source,
Pi_Param);
--没有找到字段直接返回0
IF l_Lipos = 0 THEN
RETURN(0);
END IF;
WHILE (l_Lipos < l_Length) LOOP
l_Bgchar := '';
l_Edchar := '';
IF l_Lipos <> 1 THEN
--操作字符串在中间的数据
l_Bgchar := Substr(Pi_Source,
l_Lipos - 1,
1);
END IF;
--取出字段结束后的第一个字符
l_Edchar := Substr(Pi_Source,
Length(Pi_Param) + l_Lipos,
1);
--判断字符后的第一个字符是否为特殊字符,为特殊字符就认为找到该字段的值
IF ((l_Bgchar IN (c_Trans_Char,
c_Level_Delimiter,
c_Name_Value_Delimiter,
c_Field_Delimiter) OR l_Bgchar IS NULL) AND
(l_Edchar IN (c_Trans_Char,
c_Level_Delimiter,
c_Name_Value_Delimiter,
c_Field_Delimiter) OR l_Edchar IS NULL)) THEN
RETURN(l_Lipos);
END IF;
l_Lipos := Instr(Pi_Source,
Pi_Param,
l_Lipos + 1);
IF l_Lipos = 0 THEN
RETURN(0);
END IF;
END LOOP;
--循环到结束都未找到,则表示无法找到
RETURN(0);
END;
END;
/*
2、找出该filed是否有转义符,从filed字段后=处向前推转义符个数,拼成对应都转移字符串
*/
FUNCTION Trans_Str(Pi_Source VARCHAR2,
Pi_Param VARCHAR2,
Pi_Fieldpos INT) RETURN VARCHAR2 IS
l_Str VARCHAR2(20);
l_Del_Len PLS_INTEGER := 0; --分隔符长度
l_Del_Bgpos PLS_INTEGER := 0; --=分隔符掉起始位置
l_Del_Edpos PLS_INTEGER := 0; --=分隔符掉结束位置
BEGIN
BEGIN
l_Del_Bgpos := Pi_Fieldpos + Length(Pi_Param); --=分隔符掉起始位置
--从filed结束后掉第一个与分割匹配的位置
l_Del_Edpos := Instr(Pi_Source,
c_Name_Value_Delimiter,
l_Del_Bgpos); --c_Name_Value_Delimiter := '='; --字段值分隔符
--分隔符长度:
l_Del_Len := l_Del_Edpos - l_Del_Bgpos;
l_Str := Substr(Pi_Source,
l_Del_Bgpos,
l_Del_Len);
RETURN(l_Str); --c_Trans_Char := '\'; --转义字符
END;
END Trans_Str;
/**
3、从filed的=后一直匹配到第一个“转移字符+|”到字符,并且前后都没有转移字符为止,否则向后找,如果遍历完成后都没有,则返回空字符串
*/
FUNCTION Value_Pos(Pi_Lsstr VARCHAR2,
Pi_Field_Delimiter VARCHAR2) RETURN INT IS
l_Lipos PLS_INTEGER; --字段结束位置
l_Length PLS_INTEGER;
l_Char VARCHAR2(20);
BEGIN
BEGIN
l_Length := Length(Pi_Lsstr);
l_Lipos := 0;
WHILE (l_Lipos <= l_Length) LOOP
l_Lipos := l_Lipos + 1;
l_Lipos := Instr(Pi_Lsstr,
Pi_Field_Delimiter,
l_Lipos);
l_Char := Substr(Pi_Lsstr,
l_Lipos - 1,
1);
IF l_Char <> c_Trans_Char THEN
RETURN(l_Lipos);
END IF;
END LOOP;
RETURN(0);
END;
END Value_Pos;
/**
替换掉值中掉转义符
*/
FUNCTION Value_Notranc(Pi_Values VARCHAR2) RETURN VARCHAR2 IS
l_Values VARCHAR2(32767);
BEGIN
BEGIN
l_Values := Pi_Values;
l_Values := REPLACE(l_Values,
'\\',
'\');
l_Values := REPLACE(l_Values,
'\=',
'=');
l_Values := REPLACE(l_Values,
'\|',
'|');
l_Values := REPLACE(l_Values,
'\:',
':');
RETURN(l_Values);
END;
END;
/*
取报文信息,不支持字段名(Pi_Fielna)中有特殊字符":\=|"这4个字符
查找方式:
1、找出filed字段的起始值,必须是该字段前后为空、或者前后都必须为4个特殊字符,方能匹配
2、找出该filed是否有转义符,从filed字段后=处向前推转义符个数,拼成对应都转移字符串
3、从filed的=后一直匹配到第一个“转移字符+|”到字符,并且前后都没有转移字符为止,否则向后找,如果遍历完成后都没有,则返回空字符串
4、替换掉值中的转义符
*/
FUNCTION Get_Pkgstr(Pi_Fildna IN VARCHAR2, --字段名
Pi_Pkgstr IN VARCHAR2) --报文字符串
RETURN VARCHAR2 IS
--字段对应的值(如果是循环字段则返回第一个字段的值)
l_Result VARCHAR2(32767);
l_Lisublen INT;
l_Lilen INT;
l_Lsstr VARCHAR(32767);
l_Lipos1 INT;
l_Lipos2 INT;
l_Fieldpos INT; --字段field的起始位置
l_Param VARCHAR(255);
l_Source VARCHAR2(32767);
l_Trans_Str VARCHAR(20); --转移字符串
BEGIN
l_Source := Ltrim(Rtrim(Pi_Pkgstr));
l_Param := Ltrim(Rtrim(Pi_Fildna));
l_Result := NULL;
l_Lipos1 := 0;
l_Lipos2 := 0;
l_Lisublen := 0;
l_Lsstr := l_Source;
l_Lilen := Length(l_Source);
l_Fieldpos := 0;
BEGIN
--取得l_param字段到精确位置
l_Fieldpos := Field_Pos(l_Source,
l_Param);
--无法取得字段
IF l_Fieldpos <= 0 THEN
--c_Trans_Char := '\'; --转义字符
l_Result := NULL;
GOTO Oklable;
END IF;
--如果找到,则取值
l_Lsstr := Substr(l_Lsstr,
l_Fieldpos,
l_Lilen);
----当前转移级次转义符字符串
l_Trans_Str := Trans_Str(l_Source,
l_Param,
l_Fieldpos);
l_Lipos1 := Instr(l_Lsstr,
l_Trans_Str || c_Name_Value_Delimiter) +
Nvl(Length(l_Trans_Str),
0); --c_Name_Value_Delimiter := '=' --字段值分隔符
--确定值到结束
l_Lipos2 := Value_Pos(l_Lsstr,
l_Trans_Str || c_Field_Delimiter);
IF (l_Lipos2 > (l_Lipos1 + 1)) THEN
l_Result := Ltrim(Rtrim(Substr(l_Lsstr,
l_Lipos1 + 1,
l_Lipos2 - l_Lipos1 - 1)));
--dbms_output.put_line(l_result);
ELSIF (l_Lipos2 = (l_Lipos1 + 1)) THEN
l_Result := NULL;
ELSIF (l_Lipos1 = 0 AND l_Lipos2 = 0) THEN
l_Result := NULL;
ELSE
l_Result := Ltrim(Rtrim(Substr(l_Lsstr,
l_Lipos1 + 1,
l_Lilen)));
END IF;
GOTO Oklable;
<<oklable>>
RETURN(TRIM(Value_Notranc(l_Result)));
END;
END Get_Pkgstr;
END Pkg_Pub;