oracle 中生成流水号 方法

思路:

 通过一个流水号表,记录当前最大的流水号,以便下次取用。每次取号时,将流水号表更新成大的。

涉及的表:

   流水号表hp_no:  

字段 类型
TYPE_NAME VARCHAR2(100)
START_NO VARCHAR2(100)
CURRENT_NO VARCHAR2(100)

 代码:

1)通过函数得到最大值。 有三个参数,

  第一个参数是类型,便于得到不同的流水号。

  第二个参数是前缀,用于在流水号前边放置特别的字符。

  第三个参数是生成的流水号长度。

 

代码
CREATE   OR   REPLACE   FUNCTION  Hp_Test_GetNo(
   P_TYPE_NAME   
IN     VARCHAR2   DEFAULT   '' ,   -- 类型 参数1
   P_START_NO     IN     VARCHAR2 ,   -- 前缀 参数2
   P_LENGTH       IN     NUMBER      -- 得到流水号长度 参数3
)
   
RETURN   VARCHAR2        -- 返回类型
IS
   V_RESULT       
VARCHAR2  ( 100 ) : =   '' ;    -- 结果   变量1
   V_CURRENT_NO    VARCHAR2  ( 100 ) : =   '' ;   -- 当前值  变量2
   V_NUM           NUMBER          : =   0 ;   -- 补值    变量3
   V_START_NO    VARCHAR2 ( 100 );     -- 前缀    变量4
   V_ROWID         VARCHAR2  ( 100 );     -- 要更新行的RowID  变量4
BEGIN
   V_START_NO :
= P_START_NO;   -- 参数值赋给变量

   
SELECT   COUNT  ( * )
     
INTO  V_NUM
     
FROM  HP_NO
    
WHERE  TYPE_NAME  =  P_TYPE_NAME  AND  START_NO  =  P_START_NO;     -- 得到类型与前缀相同值的数量,主要用于判断是否产生过流水号

-- 判断是否有资料 没有则产生初始值插入库中
    IF  V_NUM  =   0    -- 没有记录过时
    THEN
      V_CURRENT_NO :
=  LPAD ( ' 1 ' , P_LENGTH,  ' 0 ' );   -- 得到P_length长的0001流水号
      V_RESULT : =  V_CURRENT_NO;   -- 将前缀与流水号相连起来

      
INSERT   INTO  HP_NO(TYPE_NAME, START_NO, CURRENT_NO)
           
VALUES  (P_TYPE_NAME, P_START_NO, V_CURRENT_NO);   -- 将新的最大值记录下来
    ELSE   
      
SELECT  ROWID, CURRENT_NO  +   1
      
INTO  V_ROWID, V_CURRENT_NO
        
FROM  HP_NO
       
WHERE  TYPE_NAME  =  P_TYPE_NAME  AND  START_NO  =  P_START_NO;  -- 得到最大值加1

      V_CURRENT_NO :
=  LPAD (V_CURRENT_NO, P_LENGTH,  ' 0 ' );     
      
      
      
UPDATE  HP_NO
         
SET  CURRENT_NO  =  V_CURRENT_NO
       
WHERE  ROWID  =  V_ROWID;     -- 更新最大值
    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 ;


使用存储过程调用函数的方法:

代码
-- 调用function存储过程
CREATE   OR   REPLACE   PROCEDURE  Hp_Pro_GetTestNo
(
      v_FirstLetter 
in   varchar2 ,
      v_Result out  
varchar2
)
   
IS
      v_FirstValue 
varchar2 ( 30 );
      v_SystDate 
varchar2 ( 30 );
BEGIN
     
select  to_char(sysdate, ' yyyymm ' into  v_SystDate  from  dual;
     v_FirstValue:
= (v_FirstLetter  ||  v_SystDate);
     v_Result:
= hp_test_getno( ' HpTest '  ,v_FirstValue, 4 );
END ;


结果:

   调用存储过程Hp_Pro_GetTestNo('hp',4);

  结果为:hp2010020001

 

其它思考

一、新增时无须显示流水号,如得到得到连续流水号

 方法:

  采用流水号子表,此表用于保存没有用过的流水号。当用户取号时,首选判断子表是否含有流水号,当有时,取出一个,并删除此个(防止别另外用户取用);否则调用主表得到新流水号。

当插入失败则将当前流水号保存到流水号子表中,供下次取用。

当删除时,将当前流水号保存到流水号子表中,供下次取用。


二、新增时须显示流水号,如得到得到连续流水号

方法:

  采用流水号子表,此表用于保存没有用过的流水号。当用户取号时,首选判断子表是否含有流水号,当有时,取出一个,并删除此个(防止别另外用户取用);否则调用 主表得到新流水号。

当用户不保存或插入失败则将当前流水号保存到流水号子表中,供下次取用。

当删除时,将当前流水号保存到流水号子表中,供 下次取用。

 

其它思考的代码我没有写,有兴趣的朋友可以自己写。

 

 

 

你可能感兴趣的:(oracle)