Oracle生成流水号(SJBM_20180201_000001) 隔天重置--MYBatis集成调用

十年热恋 提交于 2019-11-29 05:37:25

使用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>



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!