1

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

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

4

3 回答 3

2

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

几乎可以满足您的要求。在某些情况下,您会在身份序列中出现缺口。(这些被称为“身份差距”,关于它们的最佳讨论在这里)。正如您所确定的,删除也会导致序列中的间隙。

为什么你需要使用 max(col) 来获取表中的行数,而你可以只使用 count(*)?如果您试图从表中获取最后一行,那么您可以这样做

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

关于更新手动管理的列的删除触发器,我认为这将是死锁和许多性能问题的潜在来源。假设您的表中有 100 万行,并且您删除了第 1 行,即您现在必须更新 999999 行以从 id 中减去 1。

于 2008-10-08T13:28:22.810 回答
0

我不确定你为什么要这样做。您可以尝试使用临时表并使用如下所示的 Identity 列“选择” 。

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(排序)

于 2008-10-08T15:56:05.103 回答
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 字段。
如果您将删除触发器放在此表上,那么您将大大减少锁定问题的可能性。

近似解决方案?

表是否需要始终保持其行号是最新的?
如果没有,您可以有一个每分钟左右运行一次的作业,它检查 rownum 中的间隙并进行更新。

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

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

于 2008-10-09T12:44:17.407 回答