88

MySQLには、この非常に便利でありながら独自仕様のREPLACE INTOSQLコマンドがあります。

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

新しいトランザクションを開始し、次にaを実行しSelect()、次にUPDATEorまたはINSERTandCOMMITを実行することは、特にアプリケーションで実行する場合は常に少し面倒です。したがって、ステートメントの2つのバージョンを常に保持します。

そのような関数をSQLServer2005に実装する簡単で普遍的な方法があるのだろうか?

4

4 に答える 4

61

これは、MSSQL について私を悩ませているものです (私のブログで暴言を吐きます)。MSSQL がサポートされていることを願っていupsertます。

@Dillie-O のコードは、古い SQL バージョン (+1 票) では良い方法ですが、基本的には 2 つの IO 操作 (existsと、次にupdateor 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', ... )

これにより、更新の場合は 1 回の IO 操作に、挿入の場合は 2 回の 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, ... )

これは本当に 1 つの IO 操作ですが、ひどいコードです :-(

于 2008-08-15T12:50:22.350 に答える
20

あなたが探している機能は、伝統的にUPSERTと呼ばれています。少なくともそれが何と呼ばれているのかを知っていると、探しているものを見つけるのに役立つかもしれません。

SQLServer2005にはこれを行うための優れた方法はないと思います。2008では、http: //www.databasejournal.com/features/mssql/article.php/3739131またはhttp://blogs.conchango.com/davidportas/archive/に示すように、これを実現するために使用できるMERGEステートメントが導入されています。 2007/11/14 / SQL-Server-2008-MERGE.aspx

マージは2005年のベータ版で利用可能でしたが、最終リリースで削除されました。

于 2008-08-01T22:22:37.823 に答える
17

アップサート/マージが行っていることは、次のような効果があります...

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

したがって、これらの記事とこの擬似コードを組み合わせることで、物事を動かすことができれば幸いです。

于 2008-08-01T22:31:36.137 に答える
10

この問題についてブログ記事を書きました。

肝心なのは、安価な更新が必要で、同時使用に対して安全であることを望む場合は、次のことを試してください。

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 つの操作があります。したがって、一般的に更新する場合、これは安全で安価なオプションです.

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

于 2008-09-21T22:05:23.887 に答える