限额控制

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. java-request与response编码问题

    一.request.setCharacterEncoding("utf-8") 二.response.setContentType("text/html;charset= ...

  2. mysql修改密码与password字段不存在mysqladmin connect to server at localhost failed

    mysqladmin: connect to server at 'localhost' failed 停止mysql服务 systemctl stop mysql 安全模式启动 chown -R m ...

  3. 字符串移位:如“abcdefghi”右移2位后变成“cdefghiab”

    函数头: //pStr 是指向以'\0'结尾的字符串指针 //steps 是要求移动的步数 void LoopMove(char *pStr, int steps) { //...... } 使用库函 ...

  4. 关于在Andoird集成开发软件中添加外部jar包的方法

    步骤必须是下面的两步,少一步都不行. 第一步是存放于项目中,第二步是导入和应用于项目中. 1.右键项目-Build Path-Configure Build Path-在Libraries目录下-点右 ...

  5. HttpComponents 基础接口/类与HTTP message的对应关系

    前提一: 什么是HTTP Message -- 遵循HTTP协议发送的消息!其格式是固定的:HTTP Message = Message Line + Message Header + Message ...

  6. android项目中的拍照和本地图片截图

    1,得到保存截图文件的地址 private static final String IMAGE_FILE_LOCATION = Environment.getExternalStorageDirect ...

  7. 教你如何架设linux邮件服务器postfix

    检查linux是否有安装postfix和dovecot 检查命令如下: Rpm  -qa |grep  postfix; Rpm –qa |grep dovecot; 如果没有显示任何数据,表明没有安 ...

  8. NPOI帮助类(Excel转DataTable、DataTable转Excel)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using NPOI.SS. ...

  9. Java动态代理-->Spring AOP

    引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...

  10. ubis文件系统的制作

    在linux-2.6.27以前,谈到Flash文件系统,大家很多时候多会想到cramfs.jffs2.yaffs2等文件系统.它们也都是基于文件系统+mtd+flash设备的架构.linux-2.6. ...