使用PLSQL创建函数,存储过程动态生成流水号
1.建立关联表TB_DPS_FLOW_NO
create table TB_DPS_FLOW_NO
(
type_name VARCHAR2(100),--类型名
start_no VARCHAR2(100),--前缀
current_no VARCHAR2(100)--当前编号
)
2.使用PLSQL建立函数Sjcl_GetSeriNo(前缀定长为4,若长度不同,需要更改函数中截取substr中数字,拷贝如下信息执行)
CREATE OR REPLACE FUNCTION Sjcl_GetSeriNo(
P_TYPE_NAME IN VARCHAR2 DEFAULT '', --类型 参数1
P_START_NO IN VARCHAR2, --前缀 参数2
P_LENGTH IN NUMBER, --得到流水号长度 参数3
V_NUMBER_COL IN VARCHAR2 -- 编码所在列名
)
RETURN VARCHAR2 --返回类型
IS
V_RESULT VARCHAR2 (100) := ''; --结果 变量1
V_CURRENT_NO VARCHAR2 (100) := ''; --当前值 变量2
V_START_NO VARCHAR2(100); --前缀 变量3
V_OLD_NO VARCHAR2(50); --原流水号
V_DATE_NO VARCHAR2(20); --当前日期编号
V_SQL VARCHAR2(4000);--SQL语句
V_OLD_DATE VARCHAR2(50);--原日期
V_OLD_NUM NUMBER; -- 原流水号数字编号
V_NEW_NUM VARCHAR2(10);--新流水号
V_TEST_NUM VARCHAR2(50);--测试编号
BEGIN
V_START_NO := P_START_NO;
-- 找出满足条件最大的流水号
V_SQL := 'SELECT MAX(' || V_NUMBER_COL || ') FROM TB_DPS_FLOW_NO WHERE TYPE_NAME ='||chr(39)|| P_TYPE_NAME ||chr(39)|| ' AND START_NO = ' ||chr(39)|| P_START_NO||chr(39) || ''; --得到类型与前缀相同值的数量,主要用于判断是否产生过流水号
EXECUTE IMMEDIATE V_SQL
INTO V_OLD_NO;
-- 将当前日期取出
V_SQL := 'SELECT SUBSTR(TO_CHAR(SYSDATE,''YYYYMMDD''), 1, 8) AS DATE_NO FROM DUAL';
EXECUTE IMMEDIATE V_SQL
INTO V_DATE_NO;
V_TEST_NUM := SUBSTR(V_OLD_NO, 10,P_LENGTH);
V_OLD_NUM := TO_NUMBER(SUBSTR(V_OLD_NO, 10,P_LENGTH));
V_NEW_NUM := TO_CHAR(V_OLD_NUM + 1);
/*
* 如果日期相同或者当前表为空
* 执行流水号为第一个00001
* 否则将上面计算好的流水号加入到新的流水号里面
*/
V_OLD_DATE := SUBSTR(V_OLD_NO, 1, 8);
IF V_OLD_NO IS NULL
THEN
V_CURRENT_NO := V_DATE_NO ||'_'|| LPAD ('1', P_LENGTH, '0'); --得到P_length长的0001流水号
INSERT INTO TB_DPS_FLOW_NO(TYPE_NAME, START_NO, CURRENT_NO)
VALUES (P_TYPE_NAME, P_START_NO, V_CURRENT_NO); --将新的最大值记录下来
ELSIF V_OLD_DATE <> V_DATE_NO
THEN
V_CURRENT_NO := V_DATE_NO||'_'|| LPAD ('1', P_LENGTH, '0'); --得到P_length长的0001流水号
UPDATE TB_DPS_FLOW_NO
SET CURRENT_NO = V_CURRENT_NO
WHERE TYPE_NAME = P_TYPE_NAME AND START_NO = P_START_NO; --更新最大值
ELSE
V_CURRENT_NO := V_DATE_NO||'_'|| LPAD (V_NEW_NUM, P_LENGTH, '0');
UPDATE TB_DPS_FLOW_NO
SET CURRENT_NO = V_CURRENT_NO
WHERE TYPE_NAME = P_TYPE_NAME AND START_NO = P_START_NO; --更新最大值
END IF;
IF V_START_NO IS NULL OR V_START_NO='' THEN
V_RESULT := V_CURRENT_NO;
ELSE
V_RESULT := V_START_NO ||'_'|| V_CURRENT_NO;
END IF;
RETURN V_RESULT;
END;
3.使用PLSQL建立存储过程 Sjcl_Pro_GetSeriNo
CREATE OR REPLACE PROCEDURE Sjcl_Pro_GetSeriNo
(
v_TypeName in varchar2,
v_Prefix in varchar2,
v_Length in number,
v_Sericol in varchar2,
v_Result out varchar2
)
IS
BEGIN
v_Result:=Sjcl_GetSeriNo(v_TypeName,v_Prefix,v_Length,v_Sericol);
END;
4、自测试验证 PLSQL
5.MyBatis集成存储过程调用(call一行,不要换行)
mapper --xml文件配置
<!-- 调用存储过程 -->
<select id="callProcedure" statementType="CALLABLE" parameterType="map">
{call Sjcl_Pro_GetSeriNo(#{v_typename,mode=IN,jdbcType=VARCHAR},#{v_prefix,mode=IN,jdbcType=VARCHAR},#{v_length,mode=IN,jdbcType=INTEGER},#{v_sericol,mode=IN,jdbcType=VARCHAR},#{result,mode=OUT,jdbcType=VARCHAR})}
</select>
来源:CSDN
作者:黯夜随风
链接:https://blog.csdn.net/weixin_39964562/article/details/79230548