0

3列の関係テーブルがあります

フォームフィールド

[formID] [int] NOT NULL,
[fieldGUID] [varchar](50) NOT NULL,
[position] [int] NOT NULL

formIDおよびfieldGUID列には、インデックス/キーに一意の制約があります。

現在、次のようにすべての関係を同時に挿入しています。

INSERT INTO formsFields(formID, fieldGUID, position)
VALUES 
(1, '{52E9A16E-B489-4577-955F-05749AB0481B}', 0),
(1, '{52E9A16E-B489-4577-955F-05749AB0481B}', 1), 
....

一意の制約により、データベースは重複を許可しませんが、挿入する行のいずれかが重複している場合、クエリは失敗します。

このような挿入を実行し、重複を無視する方法はありますか? たぶん、一時テーブルに挿入して実際のテーブルにマージすることさえありますか? このためのクエリを作成するのに少し助けが必要です。

4

1 に答える 1

0

これは、一時テーブル、集計、およびマージを使用する実装です。最大ポジション値を保存したいと仮定しています。

これを見ると、一時テーブルをスキップしてvaluesmerge. 値をソースとして使用できますが、on一致するのは 0 または 1 つだけです。複数の行があるとエラー メッセージが表示されます。

私がインデックスに凝っていると思われるかもしれませんが、それらは集計と結合を高速化します。パフォーマンスが問題にならない場合、またはスペースが問題になる場合はスキップしてください。

テーブルに既にある位置が、挿入する値よりも高くなると思わない場合、または位置が低くなっても気にしない場合は、削除できAND ff.position < source.posます。MATCHED

IF OBJECT_ID('tempdb..#formsFields2') IS NOT NULL
BEGIN
    DROP TABLE #formsFields2
END

CREATE TABLE #formsFields2 (
[formID] [int] NOT NULL,
[fieldGUID] [varchar](50) NOT NULL,
[position] [int] NOT NULL
)

CREATE NONCLUSTERED INDEX #formsFields2_IX_position
    ON #formsFields2([position])

CREATE NONCLUSTERED INDEX #formsFields2_IX_ids
    ON #formsFields2([formID], [fieldGUID])

INSERT INTO #formsFields2(formID, fieldGUID, position)
VALUES 
(1, '{52E9A16E-B489-4577-955F-05749AB0481B}', 1),
(1, '{52E9A16E-B489-4577-955F-05749AB0481B}', 2)

MERGE formsFields AS ff
USING (
    SELECT formID, fieldGUID, MAX(position)
    FROM #formsFields2
    GROUP BY formID, fieldGUID
) AS source (formID, fieldGUID, pos)
ON (ff.formID = source.formID AND ff.fieldGUID = source.fieldGUID)
WHEN MATCHED AND ff.position < source.pos THEN UPDATE SET ff.Position = source.pos
WHEN NOT MATCHED THEN INSERT VALUES (formID, fieldGUID, pos);
于 2013-07-16T02:33:04.467 に答える