2009-07-20 22 views
1

MySQLは答えません!次のように重複するキーを挿入するための解決策

基本的なクエリである

INSERT INTO destination (A,B,C) 
SELECT a1,b1,c1 
FROM source 
WHERE (selectconditions) ; 

ソースは、インサートが重複して記録するとすぐに失敗することを意味し、またはすでに先にあってもなくてもよい多数のレコードが含まれています(Aがキーであると仮定)遭遇する。

所望の挙動:INSERTまたはこれは、与えられた問題のために、所望のシナリオで

IGNORE。できる場合は挿入し、そうでない場合は続行します。

擬似C#/ Javaの:

foreach(record in selectQuery) 
{ 
    try { destination.insert(record) } 
    catch(insertionException){//squelch} 
} 

これは、クエリの最後に

AND NOT EXISTS (SELECT A FROM destination INNER JOIN source on destination.A = source.a1) 

を追加することによって、SQLで扱うことができます - あなたが挿入する前に、言い換えれば、チェックしてください。

この共通の状況を処理するための他の代替手段は何ですか?これらのテクニックの長所と短所は何ですか?そうしないと

INSERT INTO destination 
(A, B, C) 
SELECT a1, b1, c1 FROM source 
WHERE source.pk not in (SELECT pk FROM destination); 

:あなたは、共通の主キーを共有している場合

+0

いつもAを主キーにすることはできますか? –

答えて

2

一部のデータベースには、条件付きの挿入/更新を伴う操作のための明示的な構文を提供/無視します。

OracleおよびSQLServerは、たとえば、一連の述語に基づいてレコードを挿入/更新/削除/無視できるMERGE文を持っています。

INSERT INTO Target (A, B, C) 
SELECT 
    S.A, S.B, S.C 
FROM 
    Source S 
LEFT OUTER JOIN Target T ON 
    T.A = S.A AND 
    T.B = S.B AND 
    T.C = S.C 
WHERE 
    T.A IS NULL 
1

INSERT INTO destination 
(A, B, C) 
SELECT a1, b1, c1 FROM source 
WHERE a1 + b1 + c1 not in (SELECT a+b+c FROM destination); 
+1

a1 + b1 + c1とa + b + cを比較することは、ほぼ確実に悪い考えです。値がa1 = 1、b1 = 2、c1 = 3、a = 2、b = 3、c = 1の場合はどうなりますか?これらの列を連結または追加することによるパフォーマンスの低下はもちろん、インデックスの使用を損なう可能性もあります。 –

0

私はおそらく次の操作を行います:

データベース固有の構文を無視して、すでに存在するレコードを除外述語を使用して挿入を実行することができますMySQLを使用し、UNIQUEインデックスを使用して重複しないキーを強制するという贅沢さがある場合は、重複のために偶数(ノーオペレーション)アップデートでINSERT ON DUPLICATE KEY UPDATEを使用できます。

INSERT INTO Target (A, B, C) (SELECT a1, b1, c1 FROM Source) ON DUPLICATE KEY UPDATE A=A; 

これは非常に高速であり、余分なものを必要としないという利点があります。SELECT

0

あなたがしている場合:

INSERT INTO target(A, B, C) 
SELECT SA, SB, SB FROM source 
WHERE NOT EXISTS (select A, B, C from TARGET where A = SA, B = SB, C = SC) 
+0

MySQLには非標準のSQLがあります。他のベンダーがそれらをコピーしたなら、それはいいだろう。 –

関連する問題