2011-07-11 89 views
4

我在更新表格時遇到postgresql中的唯一約束問題。我有一個3列的表和一個唯一的約束列(internal_state)。這個表只有兩列,internal_state的值是1,0。 更新查詢錯誤:重複的鍵值違反PostgreSQL中的唯一約束條件

UPDATE backfeed_state SET internal_state = internal_state - 1
WHERE EXISTS (SELECT 1 FROM backfeed_state d2 WHERE d2.internal_state = 1)

運行此查詢是罰款MSSQLSERVER但在postgre它拋出唯一約束錯誤。 我的理解是在SQLServer更新所有行後,只有列上的約束正在檢查,但在更新每一行postgre後,約束正在檢查。因此,在更新第一行(internal_state值從1到0)之後,即使在更新第二行之前,postgre也正在檢查約束並拋出錯誤。

有沒有辦法避免這種情況?

回答

5

http://www.postgresql.org/docs/9.0/static/sql-createtable.html「Non-deferred Uniqueness Constraints」部分 - 「當UNIQUE或PRIMARY KEY約束不可延遲時,PostgreSQL會在插入或修改行時立即檢查唯一性。」

將您的唯一約束更改爲可延遲將延遲檢查直到更新結束。可以使用SET CONSTRAINTS在會話級別禁用(這是煩人的重複),或者使用可延遲選項重新創建唯一性約束(我不知道沒有丟棄的ALTER構造)。

+0

嗨,我們正在使用postgres8.4,其中此DEFERRABLE概念未實現的唯一約束。是否有任何其他解決方法或替代此 – subash

+0

我錯讀你的代碼;我會從這樣簡單的重寫開始:UPDATE backfeed_state SET internal_state = internal_state - 1 WHERE internal_state = 1.如果您的意圖是「翻轉」1和0,您可以嘗試刪除唯一性,使用SET進行更新internal_state = 1 - internal_state,然後加回唯一性(假設你真的想保留那個約束)。 – yieldsfalsehood

+0

我正在更新記錄,只有當我有至少一行與internal_state值'1'。這就是爲什麼我有條件'WHERE EXISTS(SELECT 1 FROM backfeed_state d2 WHERE d2.internal_state = 1)' – subash

相關問題