web-dev-qa-db-ja.com

MS SQL Serverの「INSERT IGNORE」に相当するものは何ですか?

"OPENQUERY"を使用してMS SQL ServerからMySQLデータベースにレコードを挿入しようとしていますが、実行しようとしているのは重複キーメッセージを無視することです。したがって、クエリが重複して実行された場合は、無視して続行します。

重複を無視するにはどうすればよいですか?

これが私がやっていることです:

  1. 「OpenQuery」を使用してMySQLからレコードをプルし、MySQL「A.record_id」を定義します
  2. これらのレコードをMS SQL Serverのレコードに「直接IDではなく特定の基準で」結合するここから、SQL Serverで新しい関連する「B.new_id」レコード識別子を見つけます。
  3. 検索結果をMySQLの新しいテーブルに挿入します。A.record_id、B.new_idここでは、新しいテーブルでA.record_idをそのテーブルの主キーとして設定しています。

問題は、テーブルAをテーブルBに結合するときに、探している基準に一致する2+レコードをテーブルBに見つけることがあり、これにより、データセットで値A.record_idがテーブルAに挿入する前に値A.record_idが2+回になるこれが問題の原因です。注集計関数を使用してレコードを削除できます。

18
Jaylen

特定のオプションはないと思います。しかし、それは十分に簡単です。

_insert into oldtable(. . .)
    select . . .
    from newtable
    where not exists (select 1 from oldtable where oldtable.id = newtable.id)
_

一意のキーのセットが複数ある場合は、_not exists_ステートメントを追加できます。

編集:

修正された問題:

_insert into oldtable(. . .)
    select . . .
    from (select nt.*, row_number() over (partition by id order by (select null)) as seqnum
          from newtable nt
         ) nt
    where seqnum = 1 and
          not exists (select 1 from oldtable where oldtable.id = nt.id);
_

row_number()関数は、行のグループ内の各行に連番を割り当てます。グループは_partition by_ステートメントによって定義されます。番号は1から始まり、そこから増加します。 _order by_句は、順序を気にしないことを示しています。各IDの1つの行の値は1になります。重複する行の値は1より大きくなります。 _seqnum = 1_は、IDごとに正確に1行を選択します。

13
Gordon Linoff

SQL Server 2008以降を使用している場合は、MERGEを使用して、行が存在しない場合はINSERTを実行できます。または、UPDATEを使用できます。

例:

MERGE
INTO    dataValue dv
USING   tmp_holding_DataValue t
ON      t.dateStamp = dv.dateStamp
        AND t.itemId = dv.itemId
WHEN NOT MATCHED THEN
INSERT  (dateStamp, itemId, value)
VALUES  (dateStamp, itemId, value)
10