假设MyTable的表结构(KEY, datafield1, datafield2…)
通常,我希望更新现有记录,或者插入不存在的新记录。
从本质上讲:
IF (key exists)
run update command
ELSE
run insert command
最好的写法是什么?
假设MyTable的表结构(KEY, datafield1, datafield2…)
通常,我希望更新现有记录,或者插入不存在的新记录。
从本质上讲:
IF (key exists)
run update command
ELSE
run insert command
最好的写法是什么?
当前回答
不要忘记事务。性能很好,但是简单的方法(IF EXISTS..)非常危险。 当多个线程将尝试执行插入或更新时,您可以轻松地 获取主键冲突。
由@Beau Crawford和@Esteban提供的解决方案显示了大致的想法,但容易出错。
为了避免死锁和PK违规,你可以使用如下方法:
begin tran
if exists (select * from table with (updlock,serializable) where key = @key)
begin
update table set ...
where key = @key
end
else
begin
insert into table (key, ...)
values (@key, ...)
end
commit tran
or
begin tran
update table with (serializable) set ...
where key = @key
if @@rowcount = 0
begin
insert into table (key, ...) values (@key,..)
end
commit tran
其他回答
您可以使用这个查询。适用于所有SQL Server版本。它简单明了。但是您需要使用两个查询。如果不能使用MERGE,可以使用
BEGIN TRAN
UPDATE table
SET Id = @ID, Description = @Description
WHERE Id = @Id
INSERT INTO table(Id, Description)
SELECT @Id, @Description
WHERE NOT EXISTS (SELECT NULL FROM table WHERE Id = @Id)
COMMIT TRAN
注意:请解释否定答案
虽然现在评论这个有点晚了,但我想添加一个使用MERGE的更完整的示例。
这样的Insert+Update语句通常被称为“Upsert”语句,可以在SQL Server中使用MERGE实现。
这里举了一个很好的例子: http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx
上面还解释了锁定和并发场景。
我将引用同样的内容作为参考:
ALTER PROCEDURE dbo.Merge_Foo2
@ID int
AS
SET NOCOUNT, XACT_ABORT ON;
MERGE dbo.Foo2 WITH (HOLDLOCK) AS f
USING (SELECT @ID AS ID) AS new_foo
ON f.ID = new_foo.ID
WHEN MATCHED THEN
UPDATE
SET f.UpdateSpid = @@SPID,
UpdateTime = SYSDATETIME()
WHEN NOT MATCHED THEN
INSERT
(
ID,
InsertSpid,
InsertTime
)
VALUES
(
new_foo.ID,
@@SPID,
SYSDATETIME()
);
RETURN @@ERROR;
您可以使用MERGE语句,此语句用于插入不存在的数据或更新存在的数据。
MERGE INTO Employee AS e
using EmployeeUpdate AS eu
ON e.EmployeeID = eu.EmployeeID`
你可以使用:
INSERT INTO tableName (...) VALUES (...)
ON DUPLICATE KEY
UPDATE ...
使用这个,如果已经有一个特定键的条目,那么它将更新,否则,它将插入。
IF EXISTS (SELECT * FROM [Table] WHERE ID = rowID)
UPDATE [Table] SET propertyOne = propOne, property2 . . .
ELSE
INSERT INTO [Table] (propOne, propTwo . . .)
编辑:
唉,即使对我自己不利,我也必须承认,没有选择的解决方案似乎更好,因为它们少了一步就完成了任务。