1. 程式人生 > >Oracle生成流水號(SJBM_20180201_000001) 隔天重置--MYBatis整合呼叫

Oracle生成流水號(SJBM_20180201_000001) 隔天重置--MYBatis整合呼叫

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