経験則として、私は Upsert プロシージャを作成する傾向がありますが、代理キーではなく、unique_constraint に基づいて「一致」を判断しました。
例えば。
dbo.Employee EmployeeUUID は PK で、Surrogate Key SSN は一意の制約です。
dbo.uspEmployeeUpsert would look something like this:
Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN )
Select NEWID() , LastName , FirstName , SSN
from @SomeHolderTable holder
where not exists (select null from dbo.Employee innerRealTable where
innerRealTable.SSN = holder.SSN )
Update dbo.Employee
Set EmployeeUUID = holder.EmployeeUUID
, LastName = ISNULL ( holder.LastName , e.LastName ) /* or COALESCE */
, FirstName = COALESCE ( holder.FirstName , e.FirstName )
from dbo.Employee e , @SomeHolderTable holder
Where e.SSN = holder.SSN
MERGE 関数を使用することもできます。
SSN を SurrogateKey (この場合は EmployeeUUID) に置き換えることもできます。
@SomeHolderTable とは何ですか?
xml をストアド プロシージャに渡し、それを @Variable または #Temp テーブルに分割してから、CU のロジックを記述します。D(elete) も可能ですが、通常は別の手順に分離します。
なぜ私はこのようにするのですか?
1 回のデータベース ヒットで 1、100、1000、または N 個のレコードを更新できるためです。私の論理はめったに変わらず、一箇所に孤立しています。
現在、Xml をシュレッディングするための小さなパフォーマンス ヒットがあります。しかし、99% の確率で許容できると思います。ときどき、「セットベース」以外の Upsert ルーチンを作成します。しかし、それはヘビーヒッターの使用法のためのヘビーヒッターの手順です。
それが私の見解です。
このアプローチの「セット ベース」の部分 (古い OPENXML 構文を使用) については、次の記事を参照してください。
http://msdn.microsoft.com/en-us/library/ff647768.aspx
「OpenXML を使用して一括更新と挿入を実行する」というフレーズを見つけます。
上記の URL で説明されている内容の「追加コード」バージョンを次に示します。
http://support.microsoft.com/kb/315968
編集
if exists ( select 1 from dbo.Employee e where e.SSN = holder.SSN )
BEGIN
Insert into dbo.Employee (EmployeeUUID , LastName , FirstName, SSN )
Select NEWID() , LastName , FirstName , SSN
from @SomeHolderTable holder
where not exists (select null from dbo.Employee innerRealTable where
innerRealTable.SSN = holder.SSN )
END
私は必ずしもこれを行うとは限りません。ただし、「ブールチェック」が必要な場合はオプションです。
したがって、uniqueidentifier のセットアップでは、新しいアイテムがあることがわかっているときに、「空の Guid」(00000000-0000-0000-0000-000000000000) (C# では Guid.Empty) をプロシージャに渡します。それはあなたのシナリオでの私の「-1」チェックです。
これは、「存在する場合」を確認できる方法の 1 つです。
ポットに持っているハンドの数によって異なります。
また、ポットに多くの手がある場合は、xml を細断処理することについては言及しませんでした...次に、CU ステートメントの周りで BEGIN TRAN と COMMIT TRAN を実行します (ROLLBACK を良い)。そうすれば、私の CU はアトミックで、オール オア ナッシングです。
MERGE 関数もこれを行います。しかし、MERGE の長所と短所は別のトピックです。