根据行是否存在更新或插入数据

时间:2013-01-21 21:11:05

标签: sql sql-server-2005

我有一组来自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 个答案:

答案 0 :(得分: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

现在您只需将C#中的DataTable或其他集合作为单个参数直接传递给过程。

答案 1 :(得分:1)

最有效的方法是首先尝试更新表,如果它返回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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分: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..