none
数据库中的ID重新编排 RRS feed

  • 问题

  • 表中包含ID字段,int类型,假设有1 2 3 4 5

    删除2后,3,4,5自动变为2,3,4

    插入2,则原2,3,4,5自动变为3,4,5,6

    修改2为4,则1不变,3变为2,4变为3

    希望能给出具体C#/SQL的语句

    2010年7月14日 4:43

答案

  • 建議用存儲過程控制
    下面舉個例用數據庫觸發器


    if object_id('T') is not null
     drop table T
    go
    create table T(id INT IDENTITY,name nvarchar(10))
    
    go
    
    
    CREATE TRIGGER Tr_dT ON T
    INSTEAD OF DELETE
    AS
    SET NOCOUNT ON ;
    BEGIN
    
    
     DECLARE @MinID INT
     SELECT @MinID=MIN(ID)-1 FROM DELETED
     DELETE T WHERE ID IN(SELECT ID FROM deleted) 
     
     SELECT ID=ID*1,NAME INTO # FROM T  WHERE ID>@MinID
     DELETE T WHERE ID>@MinID
     UPDATE # SET ID=@MinID,@MinID=@MinID+1
     SET IDENTITY_INSERT T ON ;
     INSERT INTO T(ID,Name)SELECT ID,Name FROM #
     SET IDENTITY_INSERT T OFF;
     DBCC CHECKIDENT('T',RESEED,@MinID)
     DROP TABLE #
     
    END
    go
    --新增數據
    insert T(Name) values('AA')
    insert T(Name) values('BB')
    insert T(Name) values('CC')
    insert T(Name) values('DD')
    insert T(Name) values('EE')
    GO
    SELECT * FROM T
    /*
    id name
    1   AA
    2   BB
    3   CC
    4   DD
    5   EE
    */
    
    go
    --測刪除
    DELETE T WHERE ID IN(2,3)
    go
    insert T(Name) values('FF')
    
    SELECT * FROM T
    /*
    id name
    1 AA
    2 DD
    3 EE
    4 FF
    */
    go
    drop table T
    


    2010年7月15日 9:57
    版主

全部回复

  • 不用那么费尽,在查询语句中重新生成一列序号列就可以了.

    如:

    select rn=row_number()over(order by lasttime),* from tb --lasttime可改为要参照排序的字段.
    
    

    如果您得到满意的答复,请将正确的回复标记为答案,以示问题解决,方便其他人浏览!Ths!
    2010年7月14日 4:56
  • 本人新手,不太明白,能再解释具体点么?最好把整句都解释下

    2010年7月14日 5:03
  • 新生成的序号会存在于数据库中么,这个id字段也为表中的重要数据,序号不是简单的显示给用户,要能够存储起来

    2010年7月14日 5:18
  • 其实这个设计思路是非常不明智的

    为啥呢?你这个任何记录的插入和删除都会导致其他记录的更新,可以想象当记录很大(几百万时候)你一个插入会导致其他几百万的数据发生更新。

    按照排序的方式貌似不能解决插入数据的问题。

    建议你把原始的需求发上来,大家看看是否有比你这个更好的解决办法。


    family as water
    2010年7月14日 7:47
  • 只是为了处理断号的话, 处理方式不够合理, 显示的时候处理一下就好了吧?

    像这种可以变来变去的东西, 没有存储的必要性, 维护的代价大于显示时候的处理.

    2010年7月15日 4:56
  • 建議用存儲過程控制
    下面舉個例用數據庫觸發器


    if object_id('T') is not null
     drop table T
    go
    create table T(id INT IDENTITY,name nvarchar(10))
    
    go
    
    
    CREATE TRIGGER Tr_dT ON T
    INSTEAD OF DELETE
    AS
    SET NOCOUNT ON ;
    BEGIN
    
    
     DECLARE @MinID INT
     SELECT @MinID=MIN(ID)-1 FROM DELETED
     DELETE T WHERE ID IN(SELECT ID FROM deleted) 
     
     SELECT ID=ID*1,NAME INTO # FROM T  WHERE ID>@MinID
     DELETE T WHERE ID>@MinID
     UPDATE # SET ID=@MinID,@MinID=@MinID+1
     SET IDENTITY_INSERT T ON ;
     INSERT INTO T(ID,Name)SELECT ID,Name FROM #
     SET IDENTITY_INSERT T OFF;
     DBCC CHECKIDENT('T',RESEED,@MinID)
     DROP TABLE #
     
    END
    go
    --新增數據
    insert T(Name) values('AA')
    insert T(Name) values('BB')
    insert T(Name) values('CC')
    insert T(Name) values('DD')
    insert T(Name) values('EE')
    GO
    SELECT * FROM T
    /*
    id name
    1   AA
    2   BB
    3   CC
    4   DD
    5   EE
    */
    
    go
    --測刪除
    DELETE T WHERE ID IN(2,3)
    go
    insert T(Name) values('FF')
    
    SELECT * FROM T
    /*
    id name
    1 AA
    2 DD
    3 EE
    4 FF
    */
    go
    drop table T
    


    2010年7月15日 9:57
    版主