質問

MySQL には、非常に便利でありながら独自の機能があります。 REPLACE INTO SQLコマンド。

これは SQL Server 2005 で簡単にエミュレートできますか?

新しいトランザクションを開始して、 Select() そして、どちらか UPDATE または INSERT そして COMMIT 特にアプリケーションで実行する場合、ステートメントの 2 つのバージョンを常に保持する場合は、常に少し面倒です。

簡単な方法はあるのだろうか 普遍的な このような機能を SQL Server 2005 に実装する方法はありますか?

役に立ちましたか?

解決

これは MSSQL に関して私を悩ませている点です (私のブログで暴言を吐く)。MSSQLをサポートしてほしい upsert.

@Dillie-O のコードは、古い SQL バージョンでは優れた方法です (+1 票) が、それでも基本的に 2 つの 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 操作が 1 回、挿入の場合は 2 回に減ります。

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, ... )

これは実際には 1 つの 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 つの操作が可能になります。したがって、通常アップデートする場合、これは安全で安価なオプションです。

また、同時に使用すると危険なものは使用しないように細心の注意を払います。運用環境では、主キー違反や行の重複が非常に簡単に発生します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top