限额控制

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. python中的高阶函数

    高阶函数英文叫Higher-order function.什么是高阶函数?我们以实际代码为例子,一步一步深入概念. 变量可以指向函数 以Python内置的求绝对值的函数abs()为例,调用该函数用以下 ...

  2. 第二百九十二节,RabbitMQ多设备消息队列-Python开发

    RabbitMQ多设备消息队列-Python开发 首先安装Python开发连接RabbitMQ的API,pika模块 pika模块为第三方模块  对于RabbitMQ来说,生产和消费不再针对内存里的一 ...

  3. (转)S5pv210 HDMI 接口在 Linux 3.0.8 驱动框架解析 (By liukun321 咕唧咕唧)

    作者:liukun321 咕唧咕唧 日期:2014.1.18 转载请标明作者.出处:http://blog.csdn.net/liukun321/article/details/18452663 本文 ...

  4. 高速入门:十分钟学会Python

    初试牛刀 如果你希望学习Python这门语言.却苦于找不到一个简短而全面的新手教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手冊(Cheat ...

  5. Unity使用JsonFX插件进行序列化

    孙广东  2015.6.25 Unity and JSON – Quick Guide: 相比較XML的沉重和密集,Json更加高效. Introduction: 什么是 Json ?假设你从未使用过 ...

  6. opencv实例一:显示一张图片

    第一个简单的实例,显示一张图片: 1)代码如下 /*************************************************************************** ...

  7. 使用tensorflow深度学习识别验证码

    除了传统的PIL包处理图片,然后用pytessert+OCR识别意外,还可以使用tessorflow训练来识别验证码. 此篇代码大部分是转载的,只改了很少地方. 代码是运行在linux环境,tesso ...

  8. tiny6410nfs挂载问题

    一.制作根文件系统 1.下载最新版的 busybox 地址:http://www.busybox.net/downloads/ 2.编译busybox.先make menuconfig ,修改以下:B ...

  9. Linux中的SELinux详解--16

    SELinux 宽容模式(permissive) 强制模式(enforcing) 关闭(disabled)  几种模式之间的转换 在CentOS6.2 中安装intel 的c++和fortran 的编 ...

  10. Maven配置默认使用的JDK版本

    问题: 创建maven项目的时候,jdk版本是1.7版本,而自己安装的是1.8版本,从而导致无法使用lambda等Java8新特性. 每次右键项目名-maven->update project ...