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>