0

我正在努力成为一名优秀的数据库开发人员并避免在此处使用循环或游标,但我不确定这是否可以做到。

我在表 A 中有代表指向不同处理队列的指针的行。在表 BI 中有需要处理的数据。表 A 中的行包含一个datetime名为的列LastUsed,用于指示处理队列上次用于处理数据的时间。每次将表 B 中的一行分配给特定队列时,都会更新此列GETUTCDATE()……这是我的循环队列问题的症结所在。

假设表 B 有 50 个数据行,表 A 有 5 个队列行。以基于集合的方式,我需要使用 an 将表 A 中的队列 ID 分配给表 B 中的所有 50 行,UPDATE并最终得到如下内容;

表 B

data record 1 - queue 1 
data record 2 - queue 2 
data record 3 - queue 3
data record 4 - queue 4
data record 5 - queue 5
data record 6 - queue 1
data record 7 - queue 2
data record 8 - queue 3
etc...

基本上,LastUsed每次更新表 B 中数据行中的队列列时,必须更新表 A 中每个队列行的列,以便下一个数据行将接收来自表 A 的“新”最旧队列行。

我已尝试创建 UDF,但无法UPDATE从 UDF 内部使用该命令。我还UPDATE使用该子句尝试了表 A 的嵌套语句OUTPUT,希望将其包装在UPDATE表 B 的另一个语句中,但 SQL Server 通知我不能嵌套这样的更新。

我被困在这里了吗?我必须使用游标或循环吗?

4

2 回答 2

0

我认为您需要使用两个单独的语句,每个表一个。然后将其包装在事务中,以便获得原子性。也许将隔离级别提高到适当的级别。

您可以使用该函数实现循环分配ROW_NUMBER,并将其取模队列数。

于 2012-08-02T21:56:36.347 回答
0
BEGIN TRAN

create table tmp_queue (age datetime, id int)
go

insert into tmp_queue values(getutcdate(), 1)
insert into tmp_queue values(getutcdate(), 2)
insert into tmp_queue values(getutcdate(), 3)
insert into tmp_queue values(getutcdate(), 4)
insert into tmp_queue values(getutcdate(), 5)
go

create table tmp_data (id int, data varchar(15))
go

insert into tmp_data values(1, 'foo')
insert into tmp_data values(2, 'foo')
insert into tmp_data values(3, 'foo')
insert into tmp_data values(4, 'foo')
insert into tmp_data values(5, 'foo')
insert into tmp_data values(6, 'foo')
insert into tmp_data values(7, 'foo')
insert into tmp_data values(8, 'foo')
insert into tmp_data values(9, 'foo')
insert into tmp_data values(10, 'foo')
insert into tmp_data values(11, 'foo')
insert into tmp_data values(12, 'foo')
insert into tmp_data values(13, 'foo')
insert into tmp_data values(14, 'foo')
insert into tmp_data values(15, 'foo')
go

create table tmp_queued_data (queue_id int, data_id int, inserted datetime)
go

insert into tmp_queued_data (queue_id, data_id, inserted)
select (RANK() OVER ( PARTITION BY id /6 ORDER BY id asc )) as queue_for_me, id, getutcdate()
from tmp_data



update tmp_queue 
set age = (select MAX(inserted)
            from tmp_queued_data
            where queue_id = tmp_queue.id)

select * from tmp_queued_data
select * from tmp_queue


ROLLBACK

这是假设你不关心那毫秒

于 2012-08-02T22:07:44.297 回答