2010-02-01 71 views
6

我執行插入行插入如下:忽略違反重複鍵索引

INSERT INTO foo (a,b,c) 
    SELECT x,y,z 
    FROM fubar 
    WHERE ... 

然而,如果一些正在插入的行違反了FOO重複的關鍵指標,我希望數據庫忽略這些行,並且不插入它們並繼續插入其他行。

有問題的數據庫是Informix 11.5。目前發生的只是數據庫拋出異常。如果我嘗試來處理異常:

ON EXCEPTION IN (-239) 
END EXCEPTION WITH RESUME; 

...它沒有幫助,因爲異常被捕獲後,整個插入被跳過。

我不認爲informix支持INSERT IGNORE或INSERT ... ON DUPLICATE KEY ...,但如果我錯了,隨時糾正我。

+0

Informix支持離開連接嗎?如果是這樣,你可以不查詢已經在foo中的行。 – 2010-02-01 18:15:46

+1

Informix確實支持LEFT JOIN。它也(IDS 11.50)支持可用於插入新行或更新現有行的MERGE。 – 2010-02-02 15:32:50

+0

我在這裏錯過了什麼嗎?爲什麼索引是唯一的?這聽起來像這個問題應該重命名爲「如何在Informix中創建一個非唯一索引?」 – 2010-02-02 15:55:26

回答

5

使用IF語句和EXISTS函數檢查存在的記錄。或者你可能包括像下面

INSERT INTO foo (a,b,c) 
SELECT x,y,z 
FROM fubar 
WHERE (NOT EXISTS(SELECT a FROM foo WHERE ...)) 
+0

這隻有用於避免重複'foo'表中的原始行。如果'fubar'表中存在重複行,則會引發異常,因爲'NOT EXISTS(SELECT a FROM foo WHERE ...)'語句中的'foo'表不包含'fubar'中的任何新行直到INSERT操作完成。 – Rockallite 2016-03-21 08:06:56

0

我不知道關於Informix在WHERE子句中存在的功能,但與SQL Server,你可以創建一個索引,使其具有唯一性,然後設置屬性有它會忽略重複鍵,因此不會在重複項上引發錯誤。它被忽略。也許Informix有類似的東西。

2

根據您是否想知道所有錯誤(通常是數據加載操作的結果),請考慮使用violations tables

START VIOLATIONS TABLE FOR foo; 

這將創建一對錶foo_vio和foo_dia以包含有關違反表上的完整性約束的行的信息。

當你已經受夠了,你用:

STOP VIOLATIONS TABLE FOR foo; 

您可以在您的休閒清理診斷表。有命令來控制使用哪個表等(我或許應該注意,這裏假設您使用的是IDS(IBM Informix Dynamic Server),而不是Informix SE或Informix OnLine。)

違規表是一種重載選項 - 適用於負載等。它們通常不用於保護普通的SQL。爲此,受保護的INSERT(使用SELECT和WHERE NOT EXISTS)非常有效 - 它要求數據已經在表中,但臨時表很容易創建。

2

有幾個其他選項可供考慮。

從版本11.50開始,Informix支持MERGE語句。這可以用來從fubar插入foo中相應行不存在的行,並用fubar中的相應行已經存在於foo(重複鍵問題)中的值更新foo中的行。

看它的另一種方式是:

SELECT fubar.* 
    FROM fubar JOIN foo ON fubar.pk = foo.pk 
    INTO TEMP duplicate_entries; 

DELETE FROM fubar WHERE pk IN (SELECT pk FROM duplicate_entries); 

INSERT INTO foo SELECT * FROM fubar; 

...processs duplicate_entries 

DROP TABLE duplicate_entries 

該清洗重複條目的源表(FUBAR)試圖插入數據前(假設它僅僅是被複制的主鍵)。duplicate_entries表包含帶重複鍵的fubar中的行 - 那些需要以某種形狀或形式進行特殊處理的行。或者你可以簡單地刪除和忽略這些行,儘管以我的經驗來看,這很少是一個好主意。

1

也許你的朋友在這個團體。防止輸入重複的行。在您的選擇中使用group by。這將強制複製到一個獨特的行。我唯一要做的就是測試一下,看看是否有任何性能問題。此外,請確保包含您希望在組中唯一的所有行,或者可以排除不重複的行。

INSERT INTO FOO(Name, Address, Age, Gadget, Price) 
select Name, Age, Gadget, Price 
from foobar 
group by Name, Age, Gadget, Price 

其中名稱,年齡,小工具,價格構成主鍵索引(或唯一鍵索引)。 另一種可能性是將重複行寫入沒有索引的錯誤表中,然後在將重複項插入新表之前先解析重複項。只需要在上面添加一個有count(*)> 1的子句。

+0

我應該看過這張貼的日期。但是,如果有人需要做類似的事情,上面的代碼是ANSI SQL,所以它應該適用於任何RDBMS。 – alaniane 2017-11-08 23:30:10