限额控制

CREATE OR REPLACE PACKAGE BODY NP_PCKG_MERCHANT_LIMIT
AS
PROCEDURE CHECK_LIMIT (
in_iplCode IN VARCHAR2, --行业编号
in_iplState IN VARCHAR2, --卡类型
in_posNo IN VARCHAR2, --商户号
in_tranAmt IN VARCHAR2, --交易金额
out_retcode OUT VARCHAR2 --返回码
)
IS
v_date VARCHAR2(8); --系统日期
--v_merchantType VARCHAR2(30); --行业类型
v_debitSingleMax NUMBER(18,2); --借记卡单笔限额
v_debitDayMax NUMBER(18,2); --借记卡日累计限额
v_debitMonthMax NUMBER(18,2); --借记卡月累计限额
v_debitYearMax NUMBER(18,2); --借记卡年累计限额
v_debitDaySum NUMBER(18,2); --借记卡日累计限额当日发生额
v_debitMonthSum NUMBER(18,2); --借记卡月累计限额当月发生额
v_debitYearSum NUMBER(18,2); --借记卡年累计限额当年发生额
v_debitLastDate NUMBER(18,2); --借记卡限额上次交易日
v_creditSingleMax NUMBER(18,2); --贷记卡单笔限额
v_creditDayMax NUMBER(18,2); --贷记卡日累计限额
v_creditMonthMax NUMBER(18,2); --贷记卡月累计限额
v_creditYearMax NUMBER(18,2); --贷记卡年累计限额
v_creditDaySum NUMBER(18,2); --贷记卡日累计限额当日发生额
v_creditMonthSum NUMBER(18,2); --贷记卡月累计限额当月发生额
v_creditYearSum NUMBER(18,2); --贷记卡年累计限额当年发生额
v_creditLastDate NUMBER(18,2); --贷记卡限额上次交易日
--v_stt VARCHAR2(1); --账户状态
BEGIN
out_retcode := ''; --取当前日期
v_date := to_char(SYSDATE, 'yyyymmdd');
----------------------------------------------------------------
-- 判断商户收单限额(设置的客商户日累计限额)
----------------------------------------------------------------
--取收单限额 也要区分借记卡 和 贷记卡 IF in_iplState = 1 THEN --是借记卡
BEGIN
SELECT
IPL_DEBIT_SINGLE,IPL_DEBIT_DAYMAX,IPL_DEBIT_MONTHMAX,IPL_DEBIT_YEARMAX
INTO
v_debitSingleMax,v_debitDayMax,v_debitMonthMax,v_debitYearMax
FROM
IM_PAY_LIMIT
WHERE
IPL_CODE = in_iplCode AND --此处需要一个参数,行业的code
IPL_STATE in('','') ; --先判断限额状态 00标示 如果是借记卡和贷记卡都可以用,或者借记卡和贷记卡只有一个能用,或者都不能用 EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
dbms_output.put_line(v_debitSingleMax);
END;
ELSIF in_iplState = 2 THEN --是贷记卡
BEGIN
SELECT
IPL_CREDIT_SINGLE,IPL_CREDIT_DAYMAX,IPL_CREDIT_MONTHMAX,IPL_CREDIT_YEARMAX
INTO
v_creditSingleMax,v_creditDayMax,v_creditMonthMax,v_creditYearMax
FROM
IM_PAY_LIMIT
WHERE
IPL_CODE = in_iplCode AND --此处需要一个参数,行业的code
IPL_STATE in('',''); --先判断限额状态 00标示 如果是借记卡和贷记卡都可以用,或者借记卡和贷记卡只有一个能用,或者都不能用 EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
END IF; --取商户年月日累计限额 ---
BEGIN
SELECT
IMD_DEBIT_DAYAMT,
IMD_DEBIT_MONTHAMT,
IMD_DEBIT_YEARAMT,
IMD_DEBIT_TRANSDAY,
IMD_CREDIT_DAYAMT,
IMD_CREDIT_MONTHAMT,
IMD_CREDIT_YEARAMT,
IMD_CREDIT_TRANSDAY
INTO
v_debitDaySum,
v_debitMonthSum,
v_debitYearSum,
v_debitLastDate,
v_creditDaySum,
v_creditMonthSum,
v_creditYearSum,
v_creditLastDate
FROM
IM_MERCHANT_DAYSUM
WHERE
IMD_POSNO = in_posNo; EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO IM_MERCHANT_DAYSUM (IMD_POSNO,IMD_DEBIT_DAYAMT,IMD_DEBIT_MONTHAMT,IMD_DEBIT_YEARAMT,IMD_CREDIT_DAYAMT,IMD_CREDIT_MONTHAMT,IMD_CREDIT_YEARAMT,IMD_DEBIT_TRANSDAY,IMD_CREDIT_TRANSDAY) VALUES (in_posNo,'0.00','0.00','0.00','0.00','0.00','0.00',v_date,v_date);
END; --判断是商户借记卡 =1 还是贷记卡 =2 START
IF in_iplState = 1 THEN
--如果是借记卡,则判断借记卡的单笔,日累计,月累计,年累计限额 v_debitSingleMax
IF TO_NUMBER(in_tranAmt) > v_debitSingleMax THEN
out_retcode := 'NPML1001'; --错误码NPML1001:超过借记卡单笔限额
--ROLLBACK;
RETURN;
END IF;
-- 判断借记卡日累计交易限额否需要清零 ,如果是昨天的交易,今天需要清零 开始
IF v_date <> v_debitLastDate THEN --here
v_debitDaySum := 0;
END IF;
-- 判断借记卡日累计交易限额否需要清零 ,如果是昨天的交易,今天需要清零 结束
IF v_debitDaySum + TO_NUMBER(in_tranAmt) > v_debitDayMax THEN --借记卡日累计限额
out_retcode := 'NPML1002'; --错误码NPML1002:超过借记卡日累计限额
--ROLLBACK;
RETURN;
END IF;
--判断借记卡月累计交易限额是否需要清零,如果是上个月的交易,则临时置空 开始
IF substr(v_date,1,6) <> substr(v_debitLastDate,1,6) THEN
v_debitMonthSum := 0;
END IF;
--判断借记卡月累计交易限额是否需要清零,如果是上个月的交易,则临时置空 结束
IF v_debitMonthSum + TO_NUMBER(in_tranAmt) > v_debitMonthMax THEN --借记卡月累计限额
out_retcode := 'NPML1003'; --错误码NPML1003:超过借记卡月累计限额
--ROLLBACK;
RETURN;
END IF;
--判断借记卡年累计交易限额是否需要清零,如果是去年的交易,则临时置空 开始
IF substr(v_date,1,4) <> substr(v_debitLastDate,1,4) THEN
v_debitYearSum := 0;
END IF;
--判断借记卡年累计交易限额是否需要清零,如果是去年的交易,则临时置空 结束
IF v_debitYearSum + TO_NUMBER(in_tranAmt) > v_debitYearMax THEN --借记卡年累计限额
out_retcode := 'NPML1004'; --错误码NPML1004:超过借记卡年累计限额
--ROLLBACK;
RETURN;
END IF;
ELSIF in_iplState = 2 THEN
--如果是贷记卡
IF TO_NUMBER(in_tranAmt) > v_creditSingleMax THEN
out_retcode := 'NPML1005'; --错误码NPML1005:超过贷记卡单笔限额
--ROLLBACK;
RETURN;
END IF;
-- 判断贷记卡日累计交易限额是否需要清零 开始
IF v_date <> v_creditLastDate THEN --here
v_creditDaySum := 0;
END IF;
-- 判断贷记卡日累计交易限额是否需要清零 结束
IF v_creditDaySum + TO_NUMBER(in_tranAmt) > v_creditDayMax THEN --贷记卡日累计限额
out_retcode := 'NPML1006'; --错误码NPML1006:超过贷记卡日累计限额
--ROLLBACK;
RETURN;
END IF;
--判断贷记卡月累计交易限额是否需要清零,如果是上个月的交易,则临时置空 开始
IF substr(v_date,1,6) <> substr(v_creditLastDate,1,6) THEN
v_creditMonthSum := 0;
END IF;
--判断贷记卡月累计交易限额是否需要清零,如果是上个月的交易,则临时置空 结束
IF v_creditMonthSum + TO_NUMBER(in_tranAmt) > v_creditMonthMax THEN --贷记卡月累计限额
out_retcode := 'NPML1007'; --错误码NPML1007:超过贷记卡月累计限额
--ROLLBACK;
RETURN;
END IF;
--判断贷记卡年累计交易限额是否需要清零,如果是去年的交易,则临时置空 开始
IF substr(v_date,1,4) <> substr(v_creditLastDate,1,4) THEN
v_creditYearSum := 0;
END IF;
--判断贷记卡年累计交易限额是否需要清零,如果是去年的交易,则临时置空 结束
IF v_creditYearSum + TO_NUMBER(in_tranAmt) > v_creditYearMax THEN --贷记卡月累计限额
out_retcode := 'NPML1008'; --错误码NPML1008:超过贷记卡年累计限额
--ROLLBACK;
RETURN;
END IF;
END IF;
--判断是商户借记卡 =1 还是贷记卡 =2 END COMMIT;
END; PROCEDURE UPDATE_LIMIT (
in_posNo IN VARCHAR2, --商户号
in_iplState IN VARCHAR2, --卡类型
in_tranAmt IN VARCHAR2, --交易金额
out_retcode OUT VARCHAR2 --返回码
)
IS
v_date VARCHAR2(8); --系统日期
v_debitDaySum NUMBER(18,2); --借记卡日累计限额当日发生额
v_debitMonthSum NUMBER(18,2); --借记卡月累计限额当月发生额
v_debitYearSum NUMBER(18,2); --借记卡年累计限额当年发生额
v_debitLastDate NUMBER(18,2); --借记卡限额上次交易日 v_creditDaySum NUMBER(18,2); --贷记卡日累计限额当日发生额
v_creditMonthSum NUMBER(18,2); --贷记卡月累计限额当月发生额
v_creditYearSum NUMBER(18,2); --贷记卡年累计限额当年发生额
v_creditLastDate NUMBER(18,2); --贷记卡限额上次交易日 BEGIN
out_retcode := ''; --取当前日期
v_date := to_char(SYSDATE, 'yyyymmdd'); --取客户日累计限额
BEGIN
SELECT
IMD_DEBIT_DAYAMT,
IMD_DEBIT_MONTHAMT,
IMD_DEBIT_YEARAMT,
IMD_CREDIT_DAYAMT,
IMD_CREDIT_MONTHAMT,
IMD_CREDIT_YEARAMT
INTO
v_debitDaySum,
v_debitMonthSum,
v_debitYearSum,
v_creditDaySum,
v_creditMonthSum,
v_creditYearSum
FROM
IM_MERCHANT_DAYSUM
WHERE
IMD_POSNO = in_posNo
FOR UPDATE; EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
--判断借记卡日累计交易限额否需要清零
IF v_date <> v_debitLastDate THEN
v_debitDaySum := 0;
END IF;
-- 判断贷记卡日累计交易限额是否需要清零
IF v_date <> v_creditLastDate THEN --here
v_creditDaySum := 0;
END IF;
--判断借记卡月累计交易限额否需要清零
IF substr(v_date,1,6) <> substr(v_debitLastDate,1,6) THEN
v_debitMonthSum := 0;
END IF;
--判断贷记卡月累计交易限额否需要清零
IF substr(v_date,1,6) <> substr(v_creditLastDate,1,6) THEN
v_creditMonthSum := 0;
END IF;
--判断借记卡年累计交易限额否需要清零
IF substr(v_date,1,4) <> substr(v_debitLastDate,1,4) THEN
v_debitYearSum := 0;
END IF;
--判断贷记卡年累计交易限额否需要清零
IF substr(v_date,1,4) <> substr(v_creditLastDate,1,4) THEN
v_creditYearSum := 0;
END IF;
--更新商户收单限额累计表 需要区分借记卡和贷记卡
IF in_iplState = 1 THEN --借记卡
UPDATE IM_MERCHANT_DAYSUM --更新借记卡收单累计限额
SET
IMD_DEBIT_DAYAMT = v_debitDaySum + TO_NUMBER(in_tranAmt),
IMD_DEBIT_MONTHAMT = v_debitMonthSum + TO_NUMBER(in_tranAmt),
IMD_DEBIT_YEARAMT = v_debitYearSum + TO_NUMBER(in_tranAmt),
IMD_DEBIT_TRANSDAY = v_date
WHERE
IMD_POSNO = in_posNo; COMMIT;
ELSIF in_iplState = 2 THEN --贷记卡
UPDATE IM_MERCHANT_DAYSUM --更新贷记卡收单累计限额
SET
IMD_CREDIT_DAYAMT = v_creditDaySum + TO_NUMBER(in_tranAmt),
IMD_CREDIT_MONTHAMT = v_creditMonthSum + TO_NUMBER(in_tranAmt),
IMD_CREDIT_YEARAMT = v_creditYearSum + TO_NUMBER(in_tranAmt),
IMD_CREDIT_TRANSDAY = v_date
WHERE
IMD_POSNO = in_posNo; COMMIT;
END IF;
END; PROCEDURE ROLL_LIMIT (
in_posNo IN VARCHAR2, --商户号
in_iplState IN VARCHAR2, --卡类型
in_orderNo IN VARCHAR2, --交易流水号
out_retcode OUT VARCHAR2 --存储过程返回码
)
IS
v_amt VARCHAR2(20);
v_transDate VARCHAR2(8);
v_nowDate VARCHAR2(8);
BEGIN
out_retcode:='';
v_nowDate:=to_char(SYSDATE, 'yyyymmdd'); --取客户日累计限额
BEGIN
SELECT
substr(NPF_TRAN_TIME,1,8),
NPF_ORDER_AMT
INTO
v_transDate,
v_amt
FROM
NP_PAY_FLOW
WHERE
NPF_FLOWNO = in_orderNo
FOR UPDATE; EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END; IF v_transDate ='' THEN out_retCode:='';
return;
END IF; --IF v_transDate<> v_nowDate then--如果不是今天的指令,不处理当日的限额
-- out_retCode:='0';
-- return;
--END IF;
--查找到该订单,并且回滚的是今天的订单
--如果是借记卡交易
--
IF in_iplState = 1 then --回滚借记卡
IF v_transDate = v_nowDate then--如果交易日期小于今天当天日期,则判断是否为本月的交易, 回滚当月和当年的
UPDATE IM_MERCHANT_DAYSUM--更新当天、本月、本年的累计额度
SET
IMD_DEBIT_DAYAMT = IMD_DEBIT_DAYAMT - v_amt,--更新当日的限额
IMD_DEBIT_MONTHAMT = IMD_DEBIT_MONTHAMT - v_amt,--更新本月的限额
IMD_DEBIT_YEARAMT = IMD_DEBIT_YEARAMT - v_amt--更新本年的限额
WHERE
IMD_POSNO = in_posNo;--商户号
COMMIT;
ELSIF v_transDate < v_nowDate then --如果交易时间不是今天,则判断是否为本月的交易
IF substr(v_transDate,1,6) = substr(v_nowDate,1,6) THEN--不是当天的交易,则判断是否为本月的交易START
UPDATE IM_MERCHANT_DAYSUM--更新本月、本年的交易
SET
IMD_DEBIT_MONTHAMT = IMD_DEBIT_MONTHAMT - v_amt,--更新本月的限额
IMD_DEBIT_YEARAMT = IMD_DEBIT_YEARAMT - v_amt --更新本年的限额
WHERE
IMD_POSNO = in_posNo;--商户号
COMMIT;
ELSIF substr(v_transDate,1,6) < substr(v_nowDate,1,6) THEN--不是当天的交易,也不是本月的交易,则判断是否为本年的交易
IF substr(v_transDate,1,4) = substr(v_nowDate,1,4) THEN--不是当天的交易,也不是本月的交易,是本年的交易
UPDATE IM_MERCHANT_DAYSUM--更新本年的交易
SET
IMD_DEBIT_YEARAMT = IMD_DEBIT_YEARAMT - v_amt--更新本年的限额
WHERE
IMD_POSNO = in_posNo;--商户号
COMMIT;
END IF;
END IF;--不是当天的交易,则判断是否为本月的交易END
END IF;--回滚借记卡结束
ELSIF in_iplState = 2 then --回滚贷记卡
IF v_transDate = v_nowDate then--如果交易日期小于今天当天日期,则判断是否为本月的交易, 回滚当月和当年的
UPDATE IM_MERCHANT_DAYSUM--更新当天、本月、本年的累计额度
SET
IMD_CREDIT_DAYAMT = IMD_CREDIT_DAYAMT - v_amt,--更新当日的限额
IMD_CREDIT_MONTHAMT = IMD_CREDIT_DAYAMT - v_amt,--更新本月的限额
IMD_CREDIT_YEARAMT = IMD_CREDIT_YEARAMT - v_amt--更新本年的限额
WHERE
IMD_POSNO = in_posNo;--商户号
COMMIT;
ELSIF v_transDate < v_nowDate then --如果交易时间不是今天,则判断是否为本月的交易
IF substr(v_transDate,1,6) = substr(v_nowDate,1,6) THEN--不是当天的交易,则判断是否为本月的交易START
UPDATE IM_MERCHANT_DAYSUM--更新本月、本年的交易
SET
IMD_CREDIT_MONTHAMT = IMD_CREDIT_MONTHAMT - v_amt,--更新本月的限额
IMD_CREDIT_YEARAMT = IMD_CREDIT_YEARAMT - v_amt--更新本年的限额
WHERE
IMD_POSNO = in_posNo;--商户号
COMMIT;
ELSIF substr(v_transDate,1,6) < substr(v_nowDate,1,6) THEN--不是当天的交易,也不是本月的交易,则判断是否为本年的交易
IF substr(v_transDate,1,4) = substr(v_nowDate,1,4) THEN--不是当天的交易,也不是本月的交易,是本年的交易
UPDATE IM_MERCHANT_DAYSUM--更新本年的交易
SET
IMD_CREDIT_YEARAMT = IMD_CREDIT_YEARAMT - v_amt --更新本年的限额
WHERE
IMD_POSNO = in_posNo;--商户号
COMMIT;
END IF;
END IF;--不是当天的交易,则判断是否为本月的交易END
END IF;--回滚借记卡结束
END IF;--回滚借记卡、贷记卡结束
--
END; END NP_PCKG_MERCHANT_LIMIT;

表结构:

Oracle存储过程--案例的更多相关文章

  1. Oracle存储过程案例集合

    注:使用的工具为PLSQL Developer 壹.while简单使用(替换字符串中的字符,和REPLACE效果一样) 注: 这里没有使用REPLACE函数 1.建立存储过程 CREATE OR RE ...

  2. 数据库周刊30丨数据安全法草案将亮相;2020数据库产业报告;云南电网上线达梦;达梦7误删Redo Log;Oracle存储过程性能瓶颈;易鲸捷实践案例……

    摘要:墨天轮数据库周刊第30期发布啦,每周1次推送本周数据库相关热门资讯.精选文章.干货文档. 热门资讯 1.数据安全法草案即将亮相:将确立数据分级分类管理.应急处置制度[摘要]数据安全法草案即将在本 ...

  3. Oracle存储过程和自定义函数

    新博客文章链接,欢迎大家评论探讨 概述 存储过程和存储函数是指存储在数据库中供所有用户程序调用的子程序叫存储过程.存储函数. 异同点: 存储过程和存储函数的相同点:完成特定功能的程序. 存储过程和存储 ...

  4. oracle存储过程和存储函数&触发器

    oracle存储过程和存储函数 指存储在数据库中供所有用户程序调用的子程序叫存储过程,存储函数 存储过程和存储函数的相同点:完成特定功能的程序 存储过程和存储函数的区别:是否用return语句返回值 ...

  5. oracle存储过程加密

    引言:平时大家在做项目的时候,经常会遇到把Oracle存储过程带到项目现场来测试系统.这时如果想对自己的存储过程进行保密,不使别人看到源代码,就可以对已有的存储过程进行加密保护.顾名思义,就是对Ora ...

  6. Oracle存储过程中跳出循环的写法

    注:本文来源于: <  Oracle存储过程中跳出循环的写法   > Oracle存储过程中跳出循环的写法 记录exit和return的用法 1:exit用来跳出循环 loop IF V_ ...

  7. oracle 存储过程

    来自:http://www.jb51.net/article/31805.htm Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 I ...

  8. Oracle存储过程语法

    原文链接:http://www.jb51.net/article/31805.htm Oracle存储过程基本语法 存储过程  1 CREATE OR REPLACE PROCEDURE 存储过程名  ...

  9. ORACLE存储过程调用Web Service

    1. 概述 最近在ESB项目中,客户在各个系统之间的服务调用大多都是在oracle存储过程中进行的,本文就oracle存储过程调用web service来进行说明.其他主流数据库,比如mysql和sq ...

随机推荐

  1. firefox插件之 vimperator 的使用

    简介: vimperator 是 Firefox浏览器下的一个插件,可以让我们像使用vim 一样使用 firefox浏览器,高效畅快,不用鼠标了.它的官网为:http://www.vimperator ...

  2. 下面关于XML叙述不正确的是( )

    A.XML标记必须关闭 B.XML是大小写敏感的 C.XML文件只能跟DTD文件一块使用 D.XML和XSL结合可以在浏览器上显示 解答:C

  3. 用C语言显示汉字的演示程序

    汉字是方块字,宽高相等的汉字库在嵌入式领域有着广泛的应用,且其解析也相对来说是比较简单的.汉字在汉字库中的索引一般会遵循GB2312/GBK编码规则,GB2312/GBK规定汉字编码由2个字节组成,其 ...

  4. (转)x264代码详细阅读之x264.c,common.c,encoder.c

    转自:http://alphamailpost.blog.163.com/blog/static/201118081201281103931932/ x264代码详细阅读第一之x264.chttp:/ ...

  5. FFMPEG的解码后的数据格式

    这两天在阅读电视转发服务器中的流媒体底层库的源码时,在看到显示部分的时候,遇到了一些疑问: 就是在用d3d做显示时候,我们显示的数据格式,指定为yv12,对于YV12的数据格式在内存中的分布,可以参考 ...

  6. Jquery实用代码片段(转)

    1.把所有带有#的空链接换成不友情的链接 $('a[href="#"]').each(function() { $(this).attr('href', 'javascript:v ...

  7. javascript -- 原型对象

    原型对象: 每个对象都有一个参考对象,这个参考对象称之为原型对象.原型对象有自己的属性和方法.当A是B的原型对象时,那 么B拥有A中的所有属性和方法. 原型对象的工作原理: 使用原型对象定义一个新的对 ...

  8. 【从0開始Tornado建站】整体设计

    Tornado是一个非堵塞的webserver,也是python的web框架中很优秀的一款.网上关于django的tutorial许多并且具体,关于tornado的使用就很少了.我想以我从0開始的方式 ...

  9. 修改php上传文件尺寸、响应时间、时区时间等设置

    修改php上传文件尺寸.响应时间 1.修改php.ini 1.post_max_size 指通过表单POST给PHP的所能接收的最大值,包括表单里的所有值,默认为8M(改为150M),看你自己需要进行 ...

  10. 算法--将Excel列索引转换成默认标识

    使用POI导入Excel时,有时对模板进行验证,假如第1行第1列错误,此时的rowIndex=columnIndex=0,与平时看到的Excel行列标记相比不太直观,因此通过相应的算法将其转换成人们熟 ...