MERGEステートメントが同じ行を複数回UPDATEまたはDELETEしようとしました。これは、ターゲット行が複数のソース行と一致する場合に発生します。 MERGEステートメントは、ターゲットテーブルの同じ行を複数回UPDATE/DELETEすることはできません。 ON句を調整して、ターゲット行が最大で1つのソース行と一致するようにするか、GROUP BY句を使用してソース行をグループ化します。
このエラーはupdateを使用して修正でき、ステートメントが存在しないことを知っています。
しかし、マージは2つのステートメントよりも高速になるため、マージでこれを実行する必要があります。
ソース:
+-----------+-----------+-------------------+---------+---------+----------+----------+
| Productid | Imagetype | Imagename | Website | Thumb90 | Thumb200 | Thumb500 |
+-----------+-----------+-------------------+---------+---------+----------+----------+
| 3144000 | small | 3144000_small.jpg | Google | 1 | 0 | 0 |
| 3144005 | medium | 3144005_medium.jpg| Google | 1 | 0 | 0 |
| 3144005 | medium | 3144005_medium.jpg| Google | 0 | 1 | 0 |
| 3144005 | medium | 3144005_medium.jpg| Google | 0 | 0 | 1 |
+-----------+-----------+-------------------+---------+---------+----------+----------+
ターゲット:
+-----------+-----------+-------------------+---------+---------+----------+----------+
| Productid | Imagetype | Imagename | Website | Thumb90 | Thumb200 | Thumb500 |
+-----------+-----------+-------------------+---------+---------+----------+----------+
| 3144000 | small | 3144000_small.jpg | Google | 0 | 0 | 0 |
| 3144000 | medium | 3144000_medium.jpg| Google | 1 | 0 | 0 |
| 3144000 | large | 3144000_large.jpg | Google | 1 | 0 | 0 |
| 3144005 | small | 3144005_small.jpg | Google | 0 | 1 | 0 |
| 3144005 | medium | 3144005_medium.jpg| Google | 0 | 0 | 0 |
| 3144005 | large | 3144005_large.jpg | Google | 0 | 0 | 1 |
+-----------+-----------+-------------------+---------+---------+----------+----------+
マージ:
+-----------+-----------+-------------------+---------+---------+----------+----------+
| Productid | Imagetype | Imagename | Website | Thumb90 | Thumb200 | Thumb500 |
+-----------+-----------+-------------------+---------+---------+----------+----------+
| 3144000 | small | 3144000_small.jpg | Google | 1 | 0 | 0 |
| 3144000 | medium | 3144000_medium.jpg| Google | 1 | 0 | 0 |
| 3144000 | large | 3144000_large.jpg | Google | 1 | 0 | 0 |
| 3144005 | small | 3144005_small.jpg | Google | 0 | 1 | 0 |
| 3144005 | medium | 3144005_medium.jpg| Google | 1 | 1 | 1 |
| 3144005 | large | 3144005_large.jpg | Google | 0 | 0 | 1 |
+-----------+-----------+-------------------+---------+---------+----------+----------+
クエリ:
MERGE INTO [luannw2016].[ImageThumbnailTrack] AS TARGET
USING #ImageThumbnailTrack AS SOURCE ON TARGET.ProductId = SOURCE.ProductId
AND TARGET.ImageType = SOURCE.ImageType
WHEN MATCHED
THEN
UPDATE
SET ImageName = SOURCE.ImageName,
Website = SOURCE.Website,
Thumb90 = SOURCE.Thumb90,
Thumb200 = SOURCE.Thumb200,
Thumb500 = SOURCE.Thumb500
WHEN NOT MATCHED
THEN
INSERT ([ProductId],[ImageType],ImageName,Website,Thumb90,Thumb200,Thumb500)
VALUES ([ProductId],[ImageType],ImageName,Website,Thumb90,Thumb200,Thumb500);
私が 正当な理由でMERGE
のファンではない であることは秘密ではありません。通常、MERGE
を使用して顧客コードを表示するときは、個別のステートメントの「古い」方法(および他の人に勧める 同じことをする 、特にMERGE
の専門家でない場合)。
マージは2つのステートメントよりも高速になるためです。
NO IT WO N'T。MERGE
は、個別のステートメントとまったく同じセマンティクスを実行します。 まったくパフォーマンス上の利点はありません です。 それを読んでください とそれがどのように機能するかを理解していることを確認してください-自信がある場合はMERGE
の方が速く、ステートメントが機能するようになったら、いくつかのテストを実行して証明してくださいそれ。結果に失望するでしょうが、少なくとも今は結論は事実に基づいています。
エラーメッセージはかなり明確だと思います。 ProductId
、ImageType
は一意ではないため、ThumbXX
列を比較に追加する必要がある場合があります。
_AND TARGET.Thumb90 = SOURCE.Thumb90
AND TARGET.Thumb200 = SOURCE.Thumb200
AND TARGET.Thumb500 = SOURCE.Thumb500
_
また、VALUES()
リストを適切にエイリアスする必要があります。
_WHEN NOT MATCHED
THEN
INSERT ([ProductId],[ImageType],...)
VALUES (SOURCE.[ProductId],SOURCE.[ImageType],...);
_
私はこれを_UPDATE ... WHERE EXISTS
_として書き、次に_INSERT ... WHERE NOT EXISTS
_として書きます(もちろん、現在のMERGE
ステートメントには必要だが欠けている適切なトランザクションにラップされます)。