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

我应该提到我正在使用 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

与其先支付搜索费用,然后使用另一个搜索进行更新,不如继续尝试更新。如果更新没有找到任何行,您仍然只支付了一次查找费用,并且不必引发异常,但您知道可以插入。

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)有很多错误,其中一些仍未解决。

当然,您应该使用表值参数,而不是一次执行一个@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

现在,您可以将 DataTable 或其他 C# 集合作为单个参数直接传递到过程中。

于 2013-01-21T21:16:13.493 回答
0

从您从服务器获得的行集合中找出哪些已经存在:

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

然后你有一个在表中的 id 列表和一个不在表中的 id 列表。然后您将有 2 个批处理操作:一个用于更新,另一个用于插入。

于 2013-01-21T21:13:47.893 回答
0

我的理解是这样的:

在前端你发出一条 sql 语句

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

一张插入表格,一张更新表格...

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