MySQL具有非常有用但专有的REPLACE INTO
SQL命令。
可以在SQL Server 2005中轻松模拟吗?
开始一个新的事务,先执行aSelect()
然后再执行UPDATE
or或INSERT
andCOMMIT
总是很麻烦,尤其是在应用程序中执行该操作时,因此始终保留该语句的2个版本。
我想知道是否有一种简单且通用的方法将这种功能实现到SQL Server 2005中?
Answers:
这让我很讨厌MSSQL(我的博客上的rant)。我希望MSSQL受支持upsert
。
@ Dillie-O的代码在较旧的SQL版本(+1票)中是个好方法,但它仍然基本上是两个IO操作(theexists
然后theupdate
或insert
)。
基本上,这篇文章有一个更好的方法:
--try an update
update tablename
set field1 = 'new value',
field2 = 'different value',
...
where idfield = 7
--insert if failed
if @@rowcount = 0 and @@error = 0
insert into tablename
( idfield, field1, field2, ... )
values ( 7, 'value one', 'another value', ... )
如果是更新,则减少为一个IO操作,如果是插入则为两个。
MS Sql2008merge
从SQL:2003标准引入:
merge tablename as target
using (values ('new value', 'different value'))
as source (field1, field2)
on target.idfield = 7
when matched then
update
set field1 = source.field1,
field2 = source.field2,
...
when not matched then
insert ( idfield, field1, field2, ... )
values ( 7, source.field1, source.field2, ... )
现在,它实际上只是一个IO操作,但是代码很糟糕:-(
MERGE
不支持该WHERE
子句,则必须使用USING
和重写该子句ON
。另外,除非添加,否则会发生WITH (HOLDLOCK)
争用,并且INSERT
可能会发生并发,其中之一由于键冲突而失败。
您正在寻找的功能通常称为UPSERT。Atleast知道它的名字可能会帮助您找到所需的内容。
我认为SQL Server 2005没有任何出色的方法可以做到这一点。2008年引入了MERGE语句,可用于完成此操作,如下所示:http : //www.databasejournal.com/features/mssql/article.php/3739131或http://blogs.conchango.com/davidportas/archive/ 2007/11/14 / SQL-Server-2008-MERGE.aspx
Merge在2005年的Beta中可用,但在最终版本中将其删除。
底线是,如果您希望廉价的更新并希望并发使用是安全的,请尝试:
update t
set hitCount = hitCount + 1
where pk = @id
if @@rowcount < 1
begin
begin tran
update t with (serializable)
set hitCount = hitCount + 1
where pk = @id
if @@rowcount = 0
begin
insert t (pk, hitCount)
values (@id,1)
end
commit tran
end
这样,您就可以进行1个更新操作,最多进行3个插入操作。因此,如果您通常进行更新,那么这是一种安全且便宜的选择。
我还要非常小心,不要使用任何对并发使用都不安全的方法。产生主键冲突或在生产中重复行真的很容易。