MySQL拥有这个非常有用但却很专业的REPLACE INTO
SQL命令。
这可以在SQL Server 2005中轻松模拟吗?
开始新的交易,执行Select()
然后UPDATE
或INSERT
和COMMIT
总是有点痛苦,尤其是在申请,因此始终保留两个版本的声明。
我想知道是否有一种简单且通用的方式将这样的功能实现到SQL Server 2005中?
答案 0 :(得分:56)
这让我对MSSQL(rant on my blog)感到恼火。我希望MSSQL支持upsert
。
@ Dillie-O的代码在较旧的SQL版本中是一个好方法(+1票),但它基本上仍然是两个IO操作(exists
然后是update
或{{1} })
在this post上有一个更好的方法,基本上是:
insert
如果是更新,则将其减少为一个IO操作,如果是插入,则将其减少为两个IO操作。
MS Sql2008引入了SQL:2003标准中的--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', ... )
:
merge
现在它只是一个IO操作,但是代码很糟糕: - (
答案 1 :(得分:20)
您正在寻找的功能传统上称为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年的测试版中可用,但是他们在最终版本中删除了它。
答案 2 :(得分:16)
upsert / merge正在做什么是......的效果。
IF EXISTS (SELECT * FROM [Table] WHERE Id = X)
UPDATE [Table] SET...
ELSE
INSERT INTO [Table]
所以希望这些文章和这些伪代码的组合可以让事情发生变化。
答案 3 :(得分:9)
我写了blog post about this issue。
最重要的是,如果您想要便宜的更新......并且您希望安全地进行并发使用。试试:
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次插入操作。所以,如果你一般更新这是一个安全便宜的选择。
我也会非常小心,不要使用任何对于并发使用不安全的东西。它很容易在生产中获得主键违规或重复行。