首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

自动生成自定义序号的存储过程有有关问题,随机会出现重复序号,请大家帮忙给看看,感激不尽

2013-12-30 
自动生成自定义序号的存储过程有问题,随机会出现重复序号,请大家帮忙给看看,感激不尽。--获取idId的格式为2

自动生成自定义序号的存储过程有问题,随机会出现重复序号,请大家帮忙给看看,感激不尽。
--获取id    Id的格式为201312280001-201312289999
CREATE PROCEDURE prBuyMakeNewBuyID
@strToday varchar(50)  --唯一的参数 格式为yyyymmdd,例如20131228   20140101
AS
set transaction isolation level serializable  --加上最严格的隔离锁
begin transaction
    declare @maxid varchar(50)                --需要返回的序号
    declare @tmpnum float                     --临时号码

    select @tmpnum=convert(float,right(isnull(max(id), @strToday+'0000'),4)) from vwbuybuys where left(id,8)=@strToday   --如果当日最大号码为20131228000,则临时号码为0 如果当日最大号码为
--201312280011,则临时号码为11
    select @tmpnum=@tmpnum+1   --给临时号码加1
    if @tmpnum<=9 and @tmpnum>=0
        select @maxid=@strToday + '000' + convert(varchar(50),@tmpnum)
    if @tmpnum<=99 and @tmpnum>=10
        select @maxid=@strToday + '00' + convert(varchar(50),@tmpnum)        
    if @tmpnum<=999 and @tmpnum>=100
        select @maxid=@strToday + '0' + convert(varchar(50),@tmpnum)
    if @tmpnum<=9999 and @tmpnum>=1000
        select @maxid=@strToday +  convert(varchar(50),@tmpnum)
    --将临时号码转换为4位,不够四位就前面加0   ,保证号码为四位
    --然后将进来的唯一参数与转换后临时号码 组合到一起

    declare @province varchar(100)
    declare @city varchar(100)
    declare @county varchar(100)
    declare @company varchar(100)
    declare @allownowsubweight int    
    select @province=province,@city=city,@county=county, @company=company from tbcommcompany
    select @allownowsubweight=allownowsubweight from tbBuyControlArgs
    
    if @allownowsubweight=1
        begin
            insert into tbbuybuys (id,inlock,assaylock,totalweightlock,carweightlock,nowsubweightlock,calclock, province,city,county1,company,carweightmicrochange,isup,othermark) values(@maxid,0,0,0,0,0,0,@province,@city,@county,@company,0,'未上传',0)
        end
    else
        begin
            insert into tbbuybuys (id,inlock,assaylock,totalweightlock,carweightlock,nowsubweightlock,calclock,province,city,county1,company,carweightmicrochange,isup,harlamount1,harlweight,meshamount1,meshweight,packsubweight,nowsubweight,othermark) values(@maxid,0,0,0,0,1,0,@province,@city,@county,@company,0,'未上传',0,0,0,0,0,0,0)
        end
    select @maxid

    --关键是程序调用这个存储过程后,两个月内发生了8次返回的id与原来的id号码相同的问题

commit transaction
GO

--补充  这段代码使用了好多年了,就是最近软件开始将高清照片存入服务器后出的问题,每条记录4张照片大小大约共1MB,因为数据增长较快,数据库的大小在不断自动增长。这台服务器的内存是512M的联想服务器。

请大家帮忙!!!分数先给100,不够再看看如何补分。

[解决办法]
唯一代码取MAX+1逻辑表面上去看无甚问题, 但,
1. 并发性引起的问题嫌疑较大,可以在select @tmpnum=convert(float,right(isnull(max(id), @strToday+'0000'),4)) from vwbuybuys where left(id,8)=@strToday  再加一个行锁定with (rowlock)(尽管已经提高了事务级别);
2 可以在正式生成后后加一个exists唯一存在性查询...
3 这段代码可以重构,可以引起一张序列表来专门管理ID值,这样哪儿出错一目了然,也方便管理。。。

[解决办法]
select @tmpnum=convert(float,right(isnull(max(id), @strToday+'0000'),4)) from vwbuybuys where left(id,8)=@strToday

这个逻辑是不是,先求最大值,然后加1,这个在大量并发的时候,就会有重复值的。

你说之前用了很长时间,没问题,现在出现了重复值,估计可能是在插入 比较大的图片时,速度慢了,更容易导致重复出现了

热点排行