解决方案 »

  1.   

    直接ID设置为GUID 这些烦恼都没有了。
      

  2.   

    我不太懂啊,大神们的回复言简意赅,但是我不是很明白,设置为GUID如何就能在取记录的时候不重复?还有,上面那篇文章我逐字逐句的还是没怎么大看懂能不能让我吃一次现成的,给我一点指导性的代码,在您百忙之中,电脑的这头有一个被折磨的死去活来的小弟在等待您的指导!
      

  3.   

    GUID可以保证不重复,不过没有顺序可言。set transaction isolation level serializable已经把你的库变成单用户访问,没有并发可言了。2000没有快照隔离,没办法,所以只能把每次update之后的100行另存到一个表,另外的会话去访问这个表或者两表关联做操作。
      

  4.   


    试试这个: select top 100 id from A with (updlock,readpast) order by getnum这个加的是更新锁,如果一个会话已经加了这个更新锁,那么其他会话再次: select top 100 id from A with (rowlock,readpast) order by getnum 就会被锁住
      

  5.   

    GUID可以保证不重复,可是不重复我也不知道取哪些记录出来啊??
    set transaction isolation level serializable
    begin tran
    commit tran
    是否意味着在 commit tran 之后 其他的会话才会进来,而我用10进程循环1000次测试获取,取出重复数据的几率还是很大的
    另外 把每次update之后的100行另存到一个表,另外的会话去访问这个表或者两表关联做操作。
    您的意思是否意味着 select * from A where id not in (select id from B)
      

  6.   


    试试这个: select top 100 id from A with (updlock,readpast) order by getnum这个加的是更新锁,如果一个会话已经加了这个更新锁,那么其他会话再次: select top 100 id from A with (rowlock,readpast) order by getnum 就会被锁住加更新锁的话 有没有可能其他会话照样取得重复的数据 我看了下资料 更新锁好像不影响其他会话查询??
      

  7.   


    试试这个: select top 100 id from A with (updlock,readpast) order by getnum这个加的是更新锁,如果一个会话已经加了这个更新锁,那么其他会话再次: select top 100 id from A with (rowlock,readpast) order by getnum 就会被锁住加更新锁的话 有没有可能其他会话照样取得重复的数据 我看了下资料 更新锁好像不影响其他会话查询??如果你的以他查询,也加上了更新锁,那么就会阻止其他查询,如果其他的查询不加更新锁,那么就可以读取到重复的数据了
      

  8.   


    你是想,top 100每次出来的都是不一样的数据吗
      

  9.   

    是的 没错 而且 我有一个字段 getnum 每取出一次 getnum+1 每次取getnum最小的100条记录
      

  10.   

    改成这样试试:WITH (UPDLOCK, HOLDLOCK)
      

  11.   


    这个我觉得top 100,是可以取出前100条记录的,但是这个readpast没什么用,用了updlock后,只会被阻塞住,所以读出来的还是那100条数据。如果你的表有10000条数据,同时有101个并发的会话,那么最后1个会话就会读取到重复的数据,这个怎么办呢?
      

  12.   


    这个我觉得top 100,是可以取出前100条记录的,但是这个readpast没什么用,用了updlock后,只会被阻塞住,所以读出来的还是那100条数据。如果你的表有10000条数据,同时有101个并发的会话,那么最后1个会话就会读取到重复的数据,这个怎么办呢?表有20万左右的数据 测试环境是10进程循环1000次每次获取100个,理论上并发最多1000条数据,上面的问题不存在
      

  13.   


    这个我觉得top 100,是可以取出前100条记录的,但是这个readpast没什么用,用了updlock后,只会被阻塞住,所以读出来的还是那100条数据。如果你的表有10000条数据,同时有101个并发的会话,那么最后1个会话就会读取到重复的数据,这个怎么办呢?表有20万左右的数据 测试环境是10进程循环1000次每次获取100个,理论上并发最多1000条数据,上面的问题不存在那就单独创建一个表:create table t(id numeric(10,0))insert into t
    values(100)declare @id numeric(10,0)select @id = id from t with(updlock)update t
    set t = id + 100select id
    from 
    (
    select id,row_number() over(order by getnum) rownum from A
    )t
    where rownum between @id-99 and @id
      

  14.   


    这个我觉得top 100,是可以取出前100条记录的,但是这个readpast没什么用,用了updlock后,只会被阻塞住,所以读出来的还是那100条数据。如果你的表有10000条数据,同时有101个并发的会话,那么最后1个会话就会读取到重复的数据,这个怎么办呢?表有20万左右的数据 测试环境是10进程循环1000次每次获取100个,理论上并发最多1000条数据,上面的问题不存在那就单独创建一个表:create table t(id numeric(10,0))insert into t
    values(100)declare @id numeric(10,0)select @id = id from t with(updlock)update t
    set t = id + 100select id
    from 
    (
    select id,row_number() over(order by getnum) rownum from A
    )t
    where rownum between @id-99 and @id

    讲实话 ,我SQL很烂, 您上面这一段我已经云里雾里,我只能附上我的完整代码,万分拜托您帮我改一改!!!
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GOALTER                    PROCEDURE dbo.gbat_getnum
           @tablename varchar(40),
           @colname varchar(40),
           @condition varchar(40),
           @condition_value varchar(40),
           @condition2 varchar(40),
           @condition2_value varchar(40),
           @getnum int
        as
        set nocount on
        set transaction isolation level serializable
        begin tran
        declare @SQL nvarchar(4000)
        declare @allid nvarchar(400)
        if @condition2=''
    begin
         set @sql='declare rs cursor for select top '+convert(varchar,@getnum)+' id from '+@tablename+' with(nolock) where '+@condition+'='+@condition_value+' order by '+@colname+''
            end
        else
    begin
         set @sql='declare rs cursor for select top '+convert(varchar,@getnum)+' id from '+@tablename+' with(nolock) where '+@condition+'='+@condition_value+' and '+@condition2+'='+@condition2_value+' order by '+@colname+''
            end
    declare @id int
    set @allid='0'
         exec(@sql)  
         OPEN rs
    FETCH NEXT FROM rs INTO @id
    WHILE @@FETCH_STATUS = 0
    BEGIN
         declare @SQL1 nvarchar(4000)
    set @sql1='update '+@tablename+' set '+@colname+'='+@colname+'+1 where id='+convert(varchar,@id)
         exec(@sql1)
    set @allid=@allid+','+CONVERT(varchar(10),@id)
    FETCH NEXT FROM rs INTO @id
    END
    CLOSE  rs 
    DEALLOCATE rs
            set @sql='select * from '+@tablename+' where id in ('+@allid+')'
         exec(@sql)
        commit tran
         
        returnGO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO
      

  15.   


    这个我觉得top 100,是可以取出前100条记录的,但是这个readpast没什么用,用了updlock后,只会被阻塞住,所以读出来的还是那100条数据。如果你的表有10000条数据,同时有101个并发的会话,那么最后1个会话就会读取到重复的数据,这个怎么办呢?表有20万左右的数据 测试环境是10进程循环1000次每次获取100个,理论上并发最多1000条数据,上面的问题不存在那就单独创建一个表:create table t(id numeric(10,0))insert into t
    values(100)declare @id numeric(10,0)select @id = id from t with(updlock)update t
    set t = id + 100select id
    from 
    (
    select id,row_number() over(order by getnum) rownum from A
    )t
    where rownum between @id-99 and @id

    讲实话 ,我SQL很烂, 您上面这一段我已经云里雾里,我只能附上我的完整代码,万分拜托您帮我改一改!!!
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GOALTER                    PROCEDURE dbo.gbat_getnum
           @tablename varchar(40),
           @colname varchar(40),
           @condition varchar(40),
           @condition_value varchar(40),
           @condition2 varchar(40),
           @condition2_value varchar(40),
           @getnum int
        as
        set nocount on
        set transaction isolation level serializable
        begin tran
        declare @SQL nvarchar(4000)
        declare @allid nvarchar(400)
        if @condition2=''
    begin
         set @sql='declare rs cursor for select top '+convert(varchar,@getnum)+' id from '+@tablename+' with(nolock) where '+@condition+'='+@condition_value+' order by '+@colname+''
            end
        else
    begin
         set @sql='declare rs cursor for select top '+convert(varchar,@getnum)+' id from '+@tablename+' with(nolock) where '+@condition+'='+@condition_value+' and '+@condition2+'='+@condition2_value+' order by '+@colname+''
            end
    declare @id int
    set @allid='0'
         exec(@sql)  
         OPEN rs
    FETCH NEXT FROM rs INTO @id
    WHILE @@FETCH_STATUS = 0
    BEGIN
         declare @SQL1 nvarchar(4000)
    set @sql1='update '+@tablename+' set '+@colname+'='+@colname+'+1 where id='+convert(varchar,@id)
         exec(@sql1)
    set @allid=@allid+','+CONVERT(varchar(10),@id)
    FETCH NEXT FROM rs INTO @id
    END
    CLOSE  rs 
    DEALLOCATE rs
            set @sql='select * from '+@tablename+' where id in ('+@allid+')'
         exec(@sql)
        commit tran
         
        returnGO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO是2000的还是2005的呢
      

  16.   

    增加一个guid字段,取消游标
    declare @g guid
    set @g=newid()
    update a
    set fguid=@g,getnum=getnum+1
    where id in
    (select top 100 id from a order by getnum,id)select * from a where fguid=@g
      

  17.   

    修改了一下,注释了一下:
    create table t(id numeric(10,0))--只有1条记录
     insert into t  
     values(0)
    go
     declare @id numeric(10,0)
     declare @c numeric(10,0)
     
     select @id = id from t with(updlock)  --取出1条数据
     
    select @c = COUNT(*) from a   --取出a表中记录总数
      update t
     set t = case when (id + 100) % @c < 100 then 0 
                  else  (id + 100) % @c 
             end --更新这条记录,比如一开始是0,那么经过计算就是100
    --选出第i+1 ~ i+100,比如一开始i是0,那么就是1~100
     select id
     from 
     (
     select id,row_number() over(order by getnum) rownum from A
     )t
     where rownum between @id+1 and @id+100
     
     
    你这个代码,用了动态语句,还在动态语句中写游标,看着也挺晕的
      

  18.   

    第 -1 个列或参数: 无法找到数据类型 guid。
    参数 '@g' 的数据类型无效。
      

  19.   


    我因为懂的不多,所以很多都是BAIDU再BAIDU,拼拼凑凑就变这样了。呵呵
      

  20.   

    第 -1 个列或参数: 无法找到数据类型 guid。
    参数 '@g' 的数据类型无效。sql2000可能还没这个类型?
    那就使用 系统时间到毫秒+随机数 的字符串做@g。不对,你不是说 用过newid()吗?应该就是它的类型就行了
      

  21.   

    'row_number' 不是可以识别的 函数名。
      

  22.   

    'row_number' 不是可以识别的 函数名。对,这个row_number是2005里才有的,所以就报错了
      

  23.   

    第 -1 个列或参数: 无法找到数据类型 guid。
    参数 '@g' 的数据类型无效。sql2000可能还没这个类型?
    那就使用 系统时间到毫秒+随机数 的字符串做@g。不对,你不是说 用过newid()吗?应该就是它的类型就行了我是在SQL语句里面order by getnum,newid()
      

  24.   

    第 -1 个列或参数: 无法找到数据类型 guid。
    参数 '@g' 的数据类型无效。sql2000可能还没这个类型?
    那就使用 系统时间到毫秒+随机数 的字符串做@g。不对,你不是说 用过newid()吗?应该就是它的类型就行了我明白你意思了 我先测试下!!多谢你们