SQL REP 2005实现MySQL REPLACE INTO?

Michael Stum 80 mysql sql-server sql-server-2005

MySQL有这个非常有用但又很合适的REPLACE INTOSQL命令.

这可以在SQL Server 2005中轻松模拟吗?

开始一个新的事务,在做了Select(),然后要么UPDATEINSERTCOMMIT始终是一个痛苦的一点点,在应用程序中做特别是当,因此能始终保持2个版本的声明.

我想知道是否有一种简单而通用的方法将这样的功能实现到SQL Server 2005中?

Keith.. 56

这让我对MSSQL感到恼火(在我的博客上咆哮).我希望MSSQL支持upsert.

@Dillie-O的代码是旧版SQL版本的一个好方法(+1票),但它仍然基本上是两个IO操作(exists然后是update或者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操作,如果是插入,则将其减少为两个IO操作.

MS Sql2008 merge从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操作,但可怕的代码:-(

  • @Keith你的合并声明不起作用.`MERGE`不支持`WHERE`子句,你必须使用`USING`和`ON`重写它.另外,除非你添加`WITH(HOLDLOCK)`,否则会出现争用并且可能发生并发`INSERT',其中一个因键冲突而失败. (3认同)

Karl Seguin.. 22

您正在寻找的功能传统上称为UPSERT.Atleast知道它叫什么可能会帮助你找到你想要的东西.

我不认为SQL Server 2005有任何好方法.2008年引入了可用于实现此目的的MERGE语句,如下所示:http://www.databasejournal.com/features/mssql/article.php/3739131http://blogs.conchango.com/davidportas/archive/一十一分之二千零七/ 14/SQL-Server的2008 MERGE.aspx

Merge在2005年的测试版中可用,但是他们在最终版本中删除了它.


Dillie-O.. 16

upsert/merge正在做什么是...的效果

IF EXISTS (SELECT * FROM [Table] WHERE Id = X)
   UPDATE [Table] SET...
ELSE
   INSERT INTO [Table]

所以希望这些文章和这些伪代码的组合可以让事情发生变化.


Sam Saffron.. 9

我写了一篇关于这个问题博客文章.

最重要的是,如果你想要廉价的更新......并且你想要安全地进行并发使用.尝试:

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次插入操作.所以,如果你一般更新这是一个安全便宜的选择.

我也会非常小心,不要使用任何对并发使用不安全的东西.它很容易在生产中获得主键违规或重复行.