SQL Server 2005实现的MySQL REPLACE INTO吗?
MySQL具有这个非常有用但适当的" REPLACE INTO" SQL命令。
可以在SQL Server 2005中轻松模拟吗?
开始一个新事务,先执行Select()然后执行UPDATE或者INSERT和COMMIT总是很麻烦,尤其是在应用程序中执行时,因此总是保留两个版本陈述。
我想知道是否有一种简单且通用的方法将这种功能实现到SQL Server 2005中?
解决方案:
我们正在寻找的功能通常称为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中可用,但在最终版本中将其删除。
upsert / merge正在做的事情对...的影响
IF EXISTS (SELECT * FROM [Table] WHERE Id = X) UPDATE [Table] SET... ELSE INSERT INTO [Table]
因此,希望这些文章和此伪代码的组合可以使事情前进。
这使我对MSSQL感到恼火(我博客上的内容)。我希望MSSQL支持upsert
。
@ Dillie-O的代码是较旧的SQL版本(+1票)中的一种好方法,但它基本上仍然是两个IO操作("存在"然后是"更新"或者"插入")
基本上,这篇文章有一个更好的方法:
--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 Sql2008从SQL:2003标准引入了merge
:
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操作,但是代码很糟糕:-(
我写了一篇有关此问题的博客文章。
最重要的是,如果我们想要廉价的更新...并且希望对并发使用安全。尝试:
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个插入操作。因此,如果我们通常进行更新,那么这是一种安全且便宜的选择。
我也将非常小心,不要使用任何对并发使用都不安全的方法。获得主键冲突或者在生产中重复行确实很容易。