2

CRUD を使用する利点と、いくつかの欠点があることは理解していますが、データベースにデータを書き込むための以下のプロセスについて、特にベスト プラクティスと考えられる長所と短所に関して、専門家からのフィードバックとアドバイスを得たいと考えています。

私は開発者として、レコードを作成する 2 つの基本的な方法に出会いました。1 つ目 (そして、私がこれまでに見たほとんどの作業で通常最も役に立たない方法) は、スタブを作成し、必要に応じてさまざまなデータが入力されたフィールド (PK を含む) を使用することです。これは通常、所有権を剥奪された大量のレコードが、実際の目的もなくデータベースの周りに浮かぶことにつながります。

2 番目の方法は、スタブをメモリに保持するだけで、オブジェクトの PK フィールドに既定値 (たとえば、-1新しいレコードを表す) を与えることです。これにより、特にレコードが後で必要ない場合に、データベースへのアクセスが最小限に抑えられます。

個人的には、2 番目の方法は最初の方法よりもはるかに寛容で簡単であることがわかりました。ただし、私が提起したい問題は、前述のデフォルト値に基づいて CRUD プロセスの側面INSERTと側面の両方を実行するストアド プロシージャを優先して、CRUD を除外するかどうかです。UPDATE

BEGIN
    IF @record_id = -1 
        INSERT ....
    ELSE
        UPDATE ....
END 

フィードバックをいただければ幸いです。

4

1 に答える 1

1

経験則として、私は 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 の長所と短所は別のトピックです。

于 2013-09-12T13:46:52.960 に答える