2013-03-14 160 views
0

我有兩個相互相同的表t1t2,但t2具有比t1更多的數據。 我正在使用此查詢來將t2中缺失的數據插入到t1ORA-00001違反的唯一約束(string.string)

insert into t1 
select * from t2 
where not exist (select * from t1 
        where t1.key1 = t2.key1 
        and t1.key2 = t2.key2) 

當這個查詢運行我得到:ORA-00001唯一約束(string.string)違反錯誤。

這兩個表格有key1key2作爲鍵。

由於唯一的約束是兩個鍵我不明白爲什麼我得到這個錯誤。

編輯:我注意到現在在「索引」中有2個約束都是類型唯一的。

第一個是:KEY1,random_column 第二個是:KEY2

遺憾的不便。

+2

的在什麼欄理想的情況下是唯一的約束? – JMan 2013-03-14 15:11:29

+0

它擊中的錯誤之一。我試圖只使用彈出錯誤消息的where語句之一。但是我得到相同的錯誤信息。 – 2013-03-14 15:15:39

回答

1

爲了防止對唯一約束有不同的理解,我假設唯一約束是兩個字段上的唯一索引。如果你在key1上有一個唯一的約束,而在key2上有一個唯一的約束,那麼當t1中有一個記錄具有相同的t2.key1值但是不同的t2.key2值時,這將失敗,因爲添加記錄會導致兩個在t1中記錄相同的key1值,這是key1上的唯一約束所禁止的。

如果這是您所擁有的,您需要一個具有兩個字段而不是列約束的唯一索引。

一種可能性是t2中的值具有NULL key1或NULL key2。

在一個表達式中,NULL輸入總是會導致NULL結果被認爲是錯誤的。

所以,如果T2與NULL key1的記錄和「值」對鍵2的值,則where子句正在評估

select * from t1 
where t1.key1 = NULL and t1.key2 = 'value2' 

這並不等同於

select * from t1 
where t1.key1 is NULL and t1.key2 = 'value2' 

代替t1.key1 = NULL將是不真實的,select將無法返回結果,存在將爲false,NOT(存在)將爲true。但是如果t1已經有這樣的記錄,那麼唯一的約束將會失敗。

所以使用這個插入語句。

insert into t1 
select * from t2 
where not exist (select * from t1 
        where (t1.key1 = t2.key1 or (t1.key1 is null and t2.key1 is null)) 
        and (t1.key2 = t2.key2 or (t1.key2 is null and t2.key2 is null))) 
+1

如果你想檢查相等性和NULL值是否相等,你可以使用'WHERE DECODE(t1.key1,t2.key1,1)= 1'而不是'WHERE t1.key1 = t2.key1'。 – Benoit 2013-03-14 15:21:54

+0

值不爲空,但檢查我的更新:> – 2013-03-14 15:32:22

0

使用減號結果集操作

insert into t1 
select * from t2 
minus 
select * from t1 
相關問題