2013-01-03 35 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