2013-01-03 34 views
0

我想将条目移动到由唯一列“orderby”维护订单的有序列表的中间。当将值移到列表中间时,我指定orderby值,并且如果值已被采用,那么旧行的orderby应该增加或减少1,具体取决于移动的方向。SQLite级联增量,维护唯一性(对于有序列表)

出于测试目的,我有这个表:

CREATE TABLE test(
orderby integer, 
UNIQUE(orderby)) 

而且我现在有以下触发:

CREATE TRIGGER [test_insert] 
BEFORE UPDATE OF [orderby] 
ON [test] 
FOR EACH ROW 
BEGIN 

UPDATE test 
SET orderby = orderby + 1 
WHERE NEW.orderby = orderby; 

END 

但是,如果由触发器创建的排序依据值未被使用这仅适用。

即,如果我运行UPDATE test SET orderby = 2 WHERE orderby = 1,它将与一个表有orderby值{1; 2},但不包含值为{1; 2; 3}

我该如何解决这个问题?或者也许完全不同?

编辑:如果我不能得到这个工作,我想我总是有选择递增所有orderby-s在一个范围内,但是,我仍然希望得到这个工作,这将允许我使用差距值或orderby并获得更高的效率。

回答

0

编辑:取代原来的答案,现在的欲望澄清。

您无法将字段定义为唯一字段,因为即使BEFORE触发器在违反唯一性之后触发。因此,使用更安全的AFTER。

下面是我想要的代码,然后进行一些测试更新。

CREATE TABLE test(pk char primary key, 
        orderby integer); 

CREATE TRIGGER test_insert 
    AFTER UPDATE OF orderby ON test 
    BEGIN 
    UPDATE test 
     set orderby = orderby + 1 
    where test.orderby >= NEW.orderby 
     and test.pk != NEW.pk; 
    END; 

insert into test (pk, orderby) values ("a", 1); 
insert into test (pk, orderby) values ("b", 2); 
insert into test (pk, orderby) values ("c", 3); 

select * from test; 

update test set orderby=1 where pk='c'; 
select * from test order by orderby"; 
update test set orderby=2 where pk='b'; 
select * from test order by orderby; 
update test set orderby=4 where pk='a'; 
select * from test order by orderby; 
+0

嗯,我刚刚看了你的编辑,很迷茫,如果我给了正确的答案与否,因为它听起来像你只需要编辑一行,即使增加1现有行可能仍然让排序依据不是唯一。 –

+0

实际上,新的条目总是在列表的末尾(并且它们的orderby值将是最高的orderby + 1),但是我需要能够对列表重新排序,并且在那里我开始遇到具有唯一orderby值的问题。稍作编辑,您的答案将与递增范围内的所有orderby-s相同,并且确实可行,如果您认为效率更高,我将使用它。 PS我会让我的问题更清楚 – tann36