1

Web サービスから取得した行のコレクションがあります。これらの行の一部は挿入され、一部は既存の行を更新します。テーブル内の ID に対してクエリを実行しない限り、確認する方法はありません。見つかったら、更新します。そうでない場合は、挿入します。

Select @ID from tbl1 where ID = @ID

IF @@ROWCOUNT = 0
BEGIN
Insert into tbl1
values(1, 'AAAA', 'BBBB', 'CCCC', 'DDD')
END
ELSE
BEGIN
UPDATE tbl1
SET 
A = @AAA,
B = @BBB,
C = @CCC,
D = @DDD
WHERE ID = @ID
END

これらの行を一度に 1 つずつストアド プロシージャに渡すことなく、テーブルに更新/挿入する最も効率的な方法を見つけようとしています。

更新 1

私は SQL Server 2005 を使用していると言いました。また、300 のレコードがある場合、300 のストアド プロシージャ コールを行いたくありません。

4

4 に答える 4

2

最も効率的な方法は、更新された0行が返された場合に最初にテーブルを更新してから、挿入のみを実行することです。例:

UPDATE tbl1
    SET 
    A = @AAA,
    B = @BBB,
    C = @CCC,
    D = @DDD
    WHERE ID = @ID    
IF @@ROWCOUNT = 0
    BEGIN
    Insert into tbl1
    values(1, 'AAAA', 'BBBB', 'CCCC', 'DDD')
    END
    ELSE
    BEGIN

END
于 2013-01-21T21:21:55.903 に答える
1

最初にシークにお金を払ってから別のシークを使用して更新するのではなく、先に進んで更新を試みてください。更新で行が見つからない場合でも、まだ 1 回のシークに対して料金が発生するだけなので、例外を発生させる必要はありませんが、挿入できることがわかります。

UPDATE dbo.tbl1 SET 
A = @AAA,
B = @BBB,
C = @CCC,
D = @DDD
WHERE ID = @ID;

IF @@ROWCOUNT = 0
BEGIN
  INSERT dbo.tbl1(ID,A,B,C,D)
    VALUES(@ID,@AAA,@BBB,@CCC,@DDD);
END

も参照できMERGEますが、(a) 構文が難解であり、(b) 多くのバグがあり、そのうちのいくつかはまだ解決されていないため、私はこれを敬遠しています。

もちろん、一度に 1 つの @ID を実行する代わりに、テーブル値パラメーターを使用する必要があります。

CREATE TYPE dbo.tbl1_type AS TABLE
( 
  ID INT UNIQUE,  
  A <datatype>,
  B <datatype>,
  C <datatype>,
  D <datatype>
);

これで、ストアド プロシージャは次のようになります。

CREATE PROCEDURE dbo.tbl1_Update
  @List AS dbo.tbl1_type READONLY
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE t 
    SET A = i.A, B = i.B, C = i.C, D = i.D
  FROM dbo.tbl1 AS t
  INNER JOIN @List AS i
  ON t.ID = i.ID;

  INSERT dbo.tbl1
  SELECT ID, A, B, C, D
    FROM @List AS i
    WHERE NOT EXISTS 
    (
      SELECT 1
      FROM dbo.tbl1 WHERE ID = i.ID
    );
END
GO

これで、C# から DataTable やその他のコレクションを単一のパラメーターとして直接プロシージャーに渡すことができます。

于 2013-01-21T21:16:13.493 に答える
0

私が理解しているのはこれです:

フロントエンドでuは単一のSQLステートメントを発行します

ArrayofIDsforInsert = select ID from tbl1 where ID not in ( array of ids at the front end)
ArrayofIDsforUpdate = (IntialArrayofids at frontend) - (ArrayofIdsforInsert)

1つのテーブルへの挿入と1つの更新テーブル..

now call the insert into table with ArrayofIds for insert
call the update table with ArrayofIds for update..
于 2013-01-21T21:21:56.830 に答える
0

サーバーから取得した行のコレクションから、既に存在する行を見つけます。

select @id from tbl1 where id in (....)

次に、テーブルにある ID とテーブルにない ID のリストがあります。2 つのバッチ操作があります。1 つは更新用、もう 1 つは挿入用です。

于 2013-01-21T21:13:47.893 に答える