2014-03-19 83 views
2

我有一個表遞增值導致約束錯誤

CREATE TABLE `tests` (`num` INTEGER UNIQUE, value VARCHAR(255)) 

創建和我加兩行到它:現在

INSERT INTO `tests` VALUES(0, "a") 
INSERT INTO `tests` VALUES(1, "b") 

我的目標是插入一行與num = 0,但爲了能夠做到這一點,我需要在這兩行上移動索引。

當我執行:

UPDATE `tests` SET `num` = `num` + 1 WHERE `num` >= 0 

我得到的錯誤:

無法執行語句由於constaint失敗(19約束失敗)

我的猜測是,它增加每個行,並且當它通過將其設置爲1來遞增第一個時,已經有一行的1,因此失敗。

在標準代碼中,這將通過向後遍歷集合來解決,有什麼辦法可以在Sqlite中做到這一點?有沒有不同的方式去做這件事?

+0

看看這個:http://stackoverflow.com/questions/1884787/how-do-i-drop-a-constraint-from-a-sqlite-3-6-21-table。 –

回答

4

更新將工作,如果你不到位,但有一個臨時表的幫助下做他們:

CREATE TEMP TABLE t2 AS SELECT * FROM tests WHERE num >= 0; 
DELETE FROM tests WHERE num >= 0; 
INSERT INTO tests SELECT num + 1, value FROM t2; 
DROP TABLE t2; 

另外,使用增量是足夠大,不會有衝突。 你必須然後再次做到這一點,回到所需值:

UPDATE tests SET num = num + 3  WHERE num  >= 0; 
UPDATE tests SET num = num - 3 + 1 WHERE num - 3 >= 0; 
+0

這是一個很好的答案,別人可能想在未來,但不會在我的情況下工作。此更新經常發生,因爲它試圖在中間需要插入操作的原始有序列表,所以臨時表是不合理的。雙重更新技巧是一個整潔的,沒有想到這一點。我一起去的答案是放棄約束,並確保我的代碼經過良好測試。 –

-1

我建議使用標識約束。這個限制會自動完成增量。

CREATE TABLE test 
(
    ID int IDENTITY(1,1) PRIMARY KEY UNIQUE, 
    value VARCHAR(255) 
) 

然後,你可以寫 INSERT INTO試驗(值)值( 'A') ,你不必擔心遞增。 (1,1)不是必需的(默認如果你只是寫身份),但你可以嘗試像ID​​ENTITY(int a,int b)這樣的其他組合 - 然後你以a值開始並按b值增加。

+0

我評論說我的目標是在開始時插入,因此Identity不合理,因爲這會給我一個比當前表中任何數字更大的數字。我需要改變這些值。 –