MySQL 有这个非常有用但专有的REPLACE INTO
SQL 命令。
这可以在 SQL Server 2005 中轻松模拟吗?
开始一个新的事务,Select()
然后做一个或者UPDATE
或者INSERT
和COMMIT
总是有点痛苦,特别是在应用程序中做它时,因此总是保留两个版本的语句。
我想知道是否有一种简单通用的方法可以在 SQL Server 2005 中实现这样的功能?
MySQL 有这个非常有用但专有的REPLACE INTO
SQL 命令。
这可以在 SQL Server 2005 中轻松模拟吗?
开始一个新的事务,Select()
然后做一个或者UPDATE
或者INSERT
和COMMIT
总是有点痛苦,特别是在应用程序中做它时,因此总是保留两个版本的语句。
我想知道是否有一种简单通用的方法可以在 SQL Server 2005 中实现这样的功能?
这让我对 MSSQL 感到恼火(在我的博客上咆哮)。我希望 MSSQL 支持upsert
。
@Dillie-O 的代码在旧 SQL 版本中是一个好方法(+1 票),但它仍然基本上是两个 IO 操作(exists
然后是update
or 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 操作,但是代码很糟糕:-(
您正在寻找的功能传统上称为 UPSERT。至少知道它的名称可能会帮助您找到所需的内容。
我不认为 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 年的测试版中可用,但他们在最终版本中将其删除。
upsert/merge 正在做的事情是......
IF EXISTS (SELECT * FROM [Table] WHERE Id = X)
UPDATE [Table] SET...
ELSE
INSERT INTO [Table]
所以希望这些文章和这个伪代码的结合可以让事情发生变化。
我写了一篇关于这个问题的博客文章。
底线是,如果您想要便宜的更新并且想要安全地并发使用,请尝试:
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 个插入操作。因此,如果您通常进行更新,这是一个安全且便宜的选择。
我也会非常小心,不要使用任何对并发使用不安全的东西。在生产中很容易出现主键违规或重复行。