1

次のようなテーブルがあるとします。

CREATE TABLE dbo.MyTestData (testdata varchar(50) NOT NULL) 

ALTER TABLE dbo.MyTestData WITH NOCHECK ADD CONSTRAINT [PK_MyTestData] PRIMARY KEY  CLUSTERED (testdata) 

また、重複がわかっている外部データのリストからアイテムの収集が完了したときに、「testdata」の一意のリストが必要な場合は、ストアドプロシージャの挿入を実行するときに、存在をテストするためにプロシージャを作成する必要があります。エラーを許容するだけですか?最も一般的な方法は何ですか?私はいつも存在のテストを行ってきましたが、昨夜議論していました...

CREATE PROCEDURE dbo.dmsInsertTestData @ptestdata VarChar(50)
AS
  SET NOCOUNT ON

  IF NOT EXISTS(SELECT testdata FROM dbo.MyTestData WHERE testdata=@ptestdata)
  BEGIN
    INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
  END

RETURN 0

または、これを実行するときにPK違反エラーをキャプチャ/無視しますか?

CREATE PROCEDURE dbo.dmsInsertTestData @ptestdata VarChar(50)
AS
  SET NOCOUNT ON
  INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
RETURN 0
4

6 に答える 6

3

エラーのチェック (つまり、「IF NOT EXISTS ...」) が機能する場合と機能しない場合があります。これは、潜在的な競合状態があるためです (別のトランザクションが IF NOT EXISTS ステートメントの後、INSERT ステートメントの前にレコードを挿入した場合)。

したがって、事前にチェックするかどうかに関係なく、失敗する可能性があるかのように INSERT ステートメントをコーディングする必要があります。

同様にチェックするかどうか(代わりにチェックしない) は、ユーザーと UI 次第です。

于 2009-01-04T20:34:41.057 に答える
2

私はいつもそれを1つのステートメントで行います:

INSERT INTO dbo.MyTestData (testdata ) VALUES (@ptestdata)
WHERE NOT EXISTS(SELECT 1 FROM dbo.MyTestData WHERE testdata=@ptestdata)
于 2009-01-04T20:37:39.180 に答える
0

ほとんどのプログラマーは、例外を回避することを提案すると思います。T-SQL のパフォーマンスの観点からはわかりませんが、たとえば .NET では、スローされた例外は追加の if/else ステートメントよりもコストがかかると思います。

于 2009-01-04T20:12:10.633 に答える
0

あなたが与えた最初の例に対する私の懸念は、それがユーザーにエラーを返していないということです. そうするように修正できますが、エラーが返されない限り使用しません。

2 つの可能性の間の懸念が大きなテーブルでのパフォーマンスである場合は、両方をテストして、一方が他方よりも大幅に高速かどうかを確認することをお勧めします。if select が特に複雑で、ほとんどの場合に挿入を行う必要がある場合は、単に失敗させた方がほとんどの場合は高速になる可能性があります。一方、不適切な入力の可能性が高く、ここに示されているように比較的複雑でない場合は、他のプロセスの方が優れている可能性があります。ただし、実際のデータ構造とデータ、および実際のクエリを使用した実際のテストのみが、さまざまな状況で異なる可能性があるため、どちらがパフォーマンスに優れているかを知ることができます。

于 2009-01-04T20:22:25.060 に答える
0

ストアドプロシージャの性質に依存すると思います。基本的に、エラーと関係がある場合 (またはプロシージャのクライアントのためにエラーをカプセル化する場合) はエラーを処理し、エラーと関係がなく、他のエラーに対してより使いやすくできない場合は、エラーを伝播させたままにする必要があります。アプリケーションのレイヤー。

ストアド プロシージャが生データを挿入するように設計されている場合、考えられるエラーの処理はアプリケーションに任せるべきだと思います。ストアド プロシージャが抽象化のレイヤーとして設計されており (特定のステートメントを実行するのではなく、特定のタスクを実行する)、エラーを処理してエラーに対して何かを実行するか、適切な方法でエラーを報告できる場合 (たとえば、適切に定義されたエラー コード) をアプリケーションに送信する必要があります。それ以外の場合は、データベースではなく、重複データを挿入していないことを確認するのはアプリケーション次第です (データベースはすでに主キーでこれを強制しています)。

于 2009-01-04T20:23:22.563 に答える
0

ユーザーフレンドリーにするために、多くの場合、SELECT を実行することをお勧めします。レコードが既に存在する場合は、それを表示および/または編集する機会をユーザーに提供します。

たとえば、ユーザーが新しい Customer レコードを追加する場合、その Customer について既に表示されている情報を確認したい場合があります。電話番号など、レコードに追加する追加情報がある場合があります。

この種のシナリオでは、レコードの追加を拒否することは、既存の重複を表示する機能を提供するよりも役に立ちません。

于 2009-01-04T20:25:49.670 に答える