CREATE OR REPLACE PROCEDURE 
/*-------------------------------------------------
 * 存储过程:  pMaxID_A
 * 功能:      获得一级编号中指定类型的最大编号
 * 参数:      t               无用的参数
 *            strIDTpye       一级编号类型
 *            intSize         该编号需要的长度
 *            strMaxID        (输出)最大一级编号
-------------------------------------------------*/
pMaxID_A (
  t               IN CHAR,
  strIDType       IN CHAR,
  strMaxID        OUT VARCHAR2
  )
AS
  intID           MAXID.MAXID%TYPE;              -- 最大编号值
  intSize         MAXIDTYPE.IDSIZE%TYPE;         -- 最大编号长度
  strLoop         MAXIDTYPE.IDLOOP%TYPE;         -- 是否是循环
  intMinValue     MAXIDTYPE.IDMAX%TYPE;          -- 范围.最小编号
  intMaxValue     MAXIDTYPE.IDMIN%TYPE;          -- 范围.最大编号
  intExist        NUMBER;                        -- 判断编号是否已经存在
  errOverSize     EXCEPTION;                     -- 超出最大编号范围
  errSizeError    EXCEPTION;                     -- 最大编号长度不能定义为 0,或最大编号范围指定错误
BEGIN
  -- 确定该最大编号类型是否已经存在
  SELECT COUNT(IDTYPE)
  INTO   intExist
  FROM   MAXID
  WHERE  IDTYPE = strIDType
  AND    ID1    = '0'
  AND    ID2    = '0';  -- 获得最大编号类型的长度
  SELECT IDSIZE,
         IDLOOP,
         IDMIN,
         IDMAX
  INTO   intSize,
         strLoop,
         intMinValue,
         intMaxValue
  FROM   MAXIDTYPE
  WHERE  IDTYPE = strIDType;  -- 返回错误:最大编号长度定义错误,长度不能为 0
  --           或最大编号范围指定错误
  IF intSize=0 OR intMaxValue>TO_NUMBER(LPAD(9, intSize, '9')) THEN
    RAISE errSizeError;
  END IF;  IF intMinValue<0 THEN
    intMinValue := 0;
  END IF;  -- 如果这个最大编号没有使用,则需要重新分配一个最大编号
  IF intExist=0 THEN
    intID := intMinValue;    INSERT INTO MAXID
      (IDTYPE, ID1, ID2, MAXID)
    VALUES
      (strIDType, '0', '0', intID);  -- 如果该编号已经存在,则在其基础上加一,并返回
  ELSE
    -- 从最大编号表中获得最大编号,并锁定该行
    SELECT MAXID
    INTO   intID
    FROM   MAXID
    WHERE  IDTYPE = strIDType
    FOR UPDATE NOWAIT;    intID := intID + 1;           -- 最大编号加一    -- 校验长度范围
    IF LENGTH(TO_CHAR(intID))>intSize THEN
      IF strLoop = '1' THEN       -- 如果是循环可用的最大编号
        intID := intMinValue;
      ELSE
        RAISE errOverSize;        -- 返回错误:超出最大编号范围
      END IF;
    END IF;    IF intID>intMaxValue AND intMaxValue!=-1 THEN
      IF strLoop = '1' THEN       -- 如果是循环可用的最大编号
        intID := intMinValue;
      ELSE
        RAISE errOverSize;        -- 返回错误:超出最大编号范围
      END IF;
    END IF;    -- 更新最大编号表
    UPDATE MAXID
    SET    MAXID  = intID
    WHERE  IDTYPE = strIDType
    AND    ID1    = '0'
    AND    ID2    = '0';
  END IF;  -- 提交改变
  COMMIT;  -- 输出最大编号
  strMaxID := LPAD(TO_CHAR(intID), intSize, '0');-- 错误捕获单元
EXCEPTION
  WHEN errOverSize THEN
    RAISE_APPLICATION_ERROR(-20001, '超出最大编号范围');
  WHEN errSizeError THEN
    RAISE_APPLICATION_ERROR(-20001, '最大编号长度定义不能为 0,或最大编号范围指定错误,请检查最大编号定义表 [ MAXIDTYPE ]。');
  WHEN NO_DATA_FOUND THEN
    RAISE_APPLICATION_ERROR(-20001, '最大编号类型未定义,请检查最大编号定义表 [ MAXIDTYPE ]。');
  WHEN OTHERS THEN
    RAISE;
END;

解决方案 »

  1.   


    if object_id('pMaxID_A','P') is not null
      drop proc pMaxID_A
    gocreate proc pMaxID_A
    (@t char(4000),
     @strIDType char(4000),
     @strMaxID varchar(max) output
    )
    as
    begin
    declare @intID int -- 最大编号值
    declare @intSize int; -- 最大编号长度
    declare @strLoop varchar(2000) -- 是否是循环
    declare @intMinValue varchar(2000) -- 范围.最小编号
    declare @intMaxValue varchar(2000) -- 范围.最大编号
    declare @intExist int -- 判断编号是否已经存在
    declare @errOverSize varchar(2000) -- 超出最大编号范围
    declare @errSizeError varchar(2000) -- 最大编号长度不能定义为 0,或最大编号范围指定错误  -- 确定该最大编号类型是否已经存在
      SELECT @intExist=COUNT(IDTYPE)
      FROM MAXID
      WHERE IDTYPE = @strIDType
      AND ID1 = '0'
      AND ID2 = '0'  -- 获得最大编号类型的长度
      SELECT @intSize=IDSIZE,
      @strLoop=IDLOOP,
      @intMinValue=IDMIN,
      @intMaxValue=IDMAX
      FROM MAXIDTYPE
      WHERE IDTYPE=@strIDType  -- 返回错误:最大编号长度定义错误,长度不能为 0
      -- 或最大编号范围指定错误
      IF @intSize=0 OR @intMaxValue>cast(replicate('9',@intSize-1)+'9' as int) 
        return '最大编号长度定义不能为 0,或最大编号范围指定错误,请检查最大编号定义表 [ MAXIDTYPE ]。'
     
      IF @intMinValue<0
        select @intMinValue=0
      
      -- 如果这个最大编号没有使用,则需要重新分配一个最大编号
      IF @intExist=0
      begin
        select @intID=@intMinValue  INSERT INTO MAXID
      (IDTYPE, ID1, ID2, MAXID)
      VALUES
      (@strIDType, '0', '0', @intID)
      end
      -- 如果该编号已经存在,则在其基础上加一,并返回
      ELSE
      begin
      -- 从最大编号表中获得最大编号,并锁定该行
      SELECT @intID=MAXID
      FROM MAXID
      WHERE IDTYPE=@strIDType  select @intID=@intID+1 -- 最大编号加一
      end 
      
      -- 校验长度范围
      IF LEN(cast(@intID as varchar))>@intSize
      IF @strLoop = '1' -- 如果是循环可用的最大编号
       select @intID=@intMinValue
      ELSE
        return '超出最大编号范围' -- 返回错误:超出最大编号范围  IF @intID>@intMaxValue AND @intMaxValue!=-1 
      IF @strLoop = '1'  -- 如果是循环可用的最大编号
        select @intID=@intMinValue
      ELSE
        return '超出最大编号范围' -- 返回错误:超出最大编号范围  -- 更新最大编号表
      UPDATE MAXID
      SET MAXID = intID
      WHERE IDTYPE=@strIDType
      AND ID1 = '0'
      AND ID2 = '0';  -- 输出最大编号
      select @strMaxID=replicate('0',@intSize-len(@intID))+cast(@intID as varchar)end
      

  2.   

    因为不清楚原表MAXID,MAXIDTYPE这些字段的数据类型,
    修改的SP中,变量定义处对应的数据类型要做相应修改.