2013-05-20 29 views
1

我試圖追查從查詢日誌中偶爾的錯誤:Oracle錯誤推遲當約束

SQLSTATE[HY000]: General error: 1 OCIStmtExecute: ORA-00001: unique constraint (FOO.BAR) violated

這似乎發生當應用程序試圖執行一個事務中以下查詢:

SET CONSTRAINT foo.bar DEFERRED 

有問題的約束條件是使用下面的DDL創建:

ALTER TABLE baz 
ADD CONSTRAINT bar 
UNIQUE (quux, duux) 
DEFERRABLE 
INITIALLY IMMEDIATE 
USING INDEX 
TABLESPACE tuux 

本質上說,運行此查詢代碼執行以下操作:

  • 開始事務
  • 推遲約束
  • 進行必要的更新
  • Undefer約束
  • 提交更新

我的問題是:上面的SET CONSTRAINT查詢如何可能導致唯一的約束違反?我確信這是有問題的查詢,因爲我有異常的堆棧跟蹤。

+1

我同意,你不應該看到一個唯一的違反約束,直到你不受約束。請注意,'set constraint x deferred'不是查詢。我懷疑約束是否真正可延遲,或者'set constraint x deferred'語句中指定的約束是否正確。 –

+0

設置約束x延遲只有在更新完成後纔會導致違規(因爲它是DDL,強制執行)。如果你只是想調試數據嘗試使用日誌錯誤http://www.oracle-base.com/articles/10g/dml-error-logging-10gr2.php – asafm

回答

-1

從(文檔)[http://docs.oracle.com/cd/B19306_01/server.102/b14200/clauses002.htm]

DEFERRABLE Clause The DEFERRABLE and NOT DEFERRABLE parameters indicate whether or not, in subsequent transactions, constraint checking can be deferred until the end of the transaction using the SET CONSTRAINT(S) statement. If you omit this clause, then the default is NOT DEFERRABLE.

你有一個獨特的鍵衝突。

由於約束是可延遲的,所以只有在執行SET CONSTRAINT foo.bar DEFERRED時才進行驗證。

+0

你的建議沒有任何意義關於我的問題。在進行任何更新之前,我正在發送'SET CONSTRAINT ... DEFERRED'。據我所知,在推遲約束之前,不可能存在預先存在的唯一密鑰違規,那麼爲什麼驗證失敗?我可以理解,如果它在交易結束時失敗了,但不是開始...... – FtDRbwLXw6

+0

你是對的。在這種情況下,我會檢查表上的約束是否定義爲「依賴」或「無效」。也許該命令觸發某種隱式驗證。 – haki