我现在的业务要求是多人同时操作数据库。
有1个表A(字段id 自增,字段xuhao 13位 char)
xuhao构成是6位区域码固定,加上地区码2位固定,加上2位年月0912加上5位数的自动增加连续的号码。
要求每年一清零。就是每年都是从00001开始的。
   我现在的是现在业务程序里面取max最大编号,然后在根据最大编号增加1,这个情况1个用户是开行的,但是如果2个以上用户同时操作表A的话就回出现重复的现象,不知道有什么好的解决办法了 ,谢谢了。
附上我的存储过程:希望大家指导。
附上存储过程: 
set ANSI_NULLS ON 
set QUOTED_IDENTIFIER ON 
GO 
ALTER PROCEDURE [dbo].[get_maxbh]  
@Date nchar(10) 
AS 
SET NOCOUNT ON 
DECLARE @Record int, @bgbh int,@CurrentError int 
Declare @xuhao  char(13) 
SET @bgbh= 

SELECT MAX(CONVERT(int,SUBSTRING(xuhao,9,5))) FROM tableA) 
SET @Record= 

SELECT  Count(*) From tableB 
WHERE date=@date 

IF EXISTS(SELECT MAX(CONVERT(int,Xuh)) FROM tableB) 
  BEGIN 
select Xuh=Xuh+1 FROM tableB WHERE date=@date 
  END  
ELSE 
  BEGIN 
INSERT INTO tableB (date,Xuh) VALUES(@date,@bgbh+1) 
  RETURN @Bgbh 
  END 
        SET NOCOUNT OFF 
 

解决方案 »

  1.   

    利用在定时作业中编写存储过程中完成.定时作业的制定企业管理器 
    --管理 
    --SQL Server代理 
    --右键作业 
    --新建作业 
    --"常规"项中输入作业名称 
    --"步骤"项 
    --新建 
    --"步骤名"中输入步骤名 
    --"类型"中选择"Transact-SQL 脚本(TSQL)" 
    --"数据库"选择执行命令的数据库 
    --"命令"中输入要执行的语句: 
                           EXEC 存储过程名 ... --该存储过程用于创建表 --确定 
    --"调度"项 
    --新建调度 
    --"名称"中输入调度名称 
    --"调度类型"中选择你的作业执行安排 
    --如果选择"反复出现" 
    --点"更改"来设置你的时间安排  
    然后将SQL Agent服务启动,并设置为自动启动,否则你的作业不会被执行 设置方法: 
    我的电脑--控制面板--管理工具--服务--右键 SQLSERVERAGENT--属性--启动类型--选择"自动启动"--确定. 
    --编号表
    CREATE TABLE tb_NO(
    Name char(2) NOT NULL,                 --编号种类的名称
    Days int NOT NULL,                     --保存的是该种编号那一天的当前编号
    Head nvarchar(10) NOT NULL DEFAULT '', --编号的前缀
    CurrentNo int NOT NULL DEFAULT 0,      --当前编号
    BHLen int NOT NULL DEFAULT 6,          --编号数字部分长度
    YearMoth int NOT NULL                  --上次生成编号的年月,格式YYYYMM
    DEFAULT CONVERT(CHAR(6),GETDATE(),112),
    DESCRIPTION NVARCHAR(50),              --编号种类说明
    TableName sysname NOT NULL,            --当前编号对应的原始表名
    KeyFieldName sysname NOT NULL,         --当前编号对应的原始表编号字段名
    PRIMARY KEY(Name,Days))--这里以一种单据的7天的资料来做测试
    INSERT tb_NO SELECT 'CG',1,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
    UNION  ALL   SELECT 'CG',2,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
    UNION  ALL   SELECT 'CG',3,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
    UNION  ALL   SELECT 'CG',4,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
    UNION  ALL   SELECT 'CG',5,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
    UNION  ALL   SELECT 'CG',6,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
    UNION  ALL   SELECT 'CG',7,'CG',0,4,200501,N'采购订单',N'tb',N'bh'
    GO--获取新编号的存储过程
    CREATE PROC p_NextBH
    @Name char(2),            --编号种类
    @Date datetime=NULL,     --要获取的当前日期,不指定则为系统当前日期
    @BH nvarchar(20) OUTPUT --新编号
    AS
    IF @Date IS NULL SET @Date=GETDATE()
    BEGIN TRAN
    --从编号表中获取新编号
    UPDATE tb_NO SET 
    @BH=Head
    +CONVERT(CHAR(6),@Date,12)
    +RIGHT(POWER(10,BHLen)
    +CASE 
    WHEN YearMoth=CONVERT(char(6),@Date,112)
    THEN CurrentNo+1
    ELSE 1 END
    ,BHLen),
    CurrentNo=CASE 
    WHEN YearMoth=CONVERT(char(6),@Date,112)
    THEN CurrentNo+1
    ELSE 1 END,
    YearMoth=CONVERT(char(6),@Date,112)
    WHERE Name=@Name 
    AND Days=DAY(@Date)
    AND YearMoth<=CONVERT(char(6),@Date,112) --如果要获取的编号在编号表中已经过期,则直接从原始表中取编号
    IF @@ROWCOUNT=0
    BEGIN
    DECLARE @s nvarchar(4000)
    SELECT @s=N'SELECT @BH='
    +QUOTENAME(Head+CONVERT(CHAR(6),@Date,12),N'''')
    +N'+RIGHT('+CAST(POWER(10,BHLen)+1 as varchar)
    +N'+ISNULL(RIGHT(MAX('+QUOTENAME(KeyFieldName)
    +N'),'+CAST(BHLen as varchar)
    +N'),0),'+CAST(BHLen as varchar)
    +N') FROM '+QUOTENAME(TableName)
    +N' WITH(XLOCK,PAGLOCK) WHERE '
    +QUOTENAME(KeyFieldName)
    +N' like '+QUOTENAME(Head+CONVERT(CHAR(6),@Date,12)+N'%',N'''')
    FROM tb_NO
    WHERE Name=@Name 
    AND Days=DAY(@Date)
    AND YearMoth>CONVERT(char(6),@Date,112)
    IF @@ROWCOUNT>0
    EXEC sp_executesql @s,N'@BH nvarchar(20) OUTPUT',@BH OUTPUT
    END
    COMMIT TRAN
    GOCREATE TABLE tb(BH char(12))
    --获取 CG 的新编号
    DECLARE @bh char(12)
    EXEC p_NextBH 'CG','2005-1-1',@bh OUT
    SELECT @bh
    --结果: CG0501010001EXEC p_NextBH 'CG','2005-1-1',@bh OUT
    SELECT @bh
    --结果: CG0501010002EXEC p_NextBH 'CG','2005-1-2',@bh OUT
    SELECT @bh
    --结果: CG0501020001EXEC p_NextBH 'CG','2005-2-2',@bh OUT
    SELECT @bh
    --结果: CG0402020001EXEC p_NextBH 'CG','2004-2-2',@bh OUT
    SELECT @bh
    --结果: CG0402020001
    GO