INSERT test
SELECT *
FROM [sourceDB].[dbo].[table1] as source
LEFT OUTER JOIN [testDB].[dbo].[table1] as test
ON source.[PKcolumn] = test.[PKcolumn]
WHERE test.[PKcolumn] IS NULL
これの何が悪いのか話しましょう。最初の選択*には、ソースからのすべての列が含まれ、その中にテストが含まれます。これは、挿入する予定のテーブルよりも明らかに多くの列です。いくつかの理由から、insert ステートメントで select * を使用することは決して受け入れられません。
まず、誰かが列の順序またはテーブルの構造を変更すると、挿入が壊れます。第二に、このような結合がある場合、列の数が間違っています。第三に、元の順序が異なる場合、同じ列を持っていても、データを磨耗した列に入れることができます。それらが同様のデータ型であり、データが適合するか暗黙的に変換できる場合、データベースはこれを停止しません。
次に、select の別名を挿入の宛先として使用することはできません。実際のテーブル名を参照する必要があります。
最後に、すべての挿入で列リストを使用しないのは、非常に不適切な方法です。これはメンテナンスに役立ち、選択した列が挿入内の列と一致するかどうかを確認できます。さらに、自動生成されたフィールドがある場合は、列リストを使用する必要があります。そうしないと、自動生成されたフィールドに挿入しようとするため、エラーが発生します。
したがって、ステートメントは次のようになります。
INSERT [testDB].[dbo].[table1] (field1, field2, field3)
SELECT source.field1, source.field2, source.field3
FROM [sourceDB].[dbo].[table1] as source
LEFT OUTER JOIN [testDB].[dbo].[table1] as test
ON source.[PKcolumn] = test.[PKcolumn]
WHERE test.[PKcolumn] IS NULL
または(おそらくより効率的です。特定の状況でテストする必要があります):
INSERT [testDB].[dbo].[table1] (field1, field2, field3)
SELECT source.field1, source.field2, source.field3
FROM [sourceDB].[dbo].[table1] as source
WHERE NOT EXISTS (SELECT * FROM testDB].[dbo].[table1] test
WHERE source.[PKcolumn]=test.[PKcolumn])