Sybase表中的行号

时间:2008-10-08 12:51:23

标签: sql sybase

Sybase db表没有自行更新行号的概念。但是,对于其中一个模块,我需要存在与数据库中每一行对应的rownumber,以便max(Column)总是告诉我表中的行数。

我以为我会引入一个int列并不断更新此列以跟踪行号。但是,如果删除,我在更新此列时遇到问题。我应该在delete触发器中使用什么SQL来更新此列?

3 个答案:

答案 0 :(得分:2)

您可以使用标识列轻松地为每行分配唯一编号。标识可以是数字或整数(在ASE12 +中)。

这将几乎做你需要的。在某些情况下,您将在身份序列中获得差距。 (这些被称为“身份差距”,对它们的最佳讨论是here)。删除也会导致序列中的间隙,如您所识别的那样。

当你可以使用count(*)时,为什么需要使用max(col)来获取表中的行数?如果你想从表中获取最后一行,那么你可以做

select * from table where column = (select max(column) from table).

关于更新手动管理列的删除触发器,我认为这可能是死锁的潜在根源,以及许多性能问题。想象一下,你的表中有100万行,你删除第1行,你现在需要更新的999999行,从id中减去1。

答案 1 :(得分:0)

我不确定你为什么要这样做。您可以尝试使用临时表和"select into" with an Identity column,如下所示。

create table test
 ( 
 col1 int,
 col2 varchar(3)
 )

 insert into test values (100, "abc")
 insert into test values (111, "def")
 insert into test values (222, "ghi")
 insert into test values (300, "jkl")
 insert into test values (400, "mno")

select rank = identity(10), col1 into #t1 from Test
select * from #t1

delete from test where col2="ghi"

select rank = identity(10), col1 into #t2 from Test
select * from #t2

drop table test
drop table #t1
drop table #t2

这会给你一个动态id(各种各样)

答案 2 :(得分:0)

删除触发器

CREATE TRIGGER tigger ON myTable FOR DELETE
AS 
update myTable 
set id = id - (select count(*) from deleted d where d.id < t.id)  
from myTable t

避免锁定问题

您可以添加一个额外的表(它连接到您的主表),如下所示:

CREATE TABLE rowCounter 
(id    int,      -- foreign key to main table
 rownum int) 

...并使用此表中的rownum字段 如果您将删除触发器放在此表上,那么您将极大地减少锁定问题的可能性。

近似解决方案?

表格是否需要始终保持rownumbers的最新状态?
如果没有,你可以拥有一个每分钟左右运行一次的工作,它会检查rownum中的间隙,然后进行更新。

问题:rownumbers是否必须反映插入行的顺序? 如果没有,您可以做更少的更新,但只更新最近的行,将它们“移动”到间隙中。

如果您希望我发布这些想法的SQL,请发表评论。