SQL Server 2005 の MySQL REPLACE INTO の実装?
-
08-06-2019 - |
質問
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 つの操作が可能になります。したがって、通常アップデートする場合、これは安全で安価なオプションです。
また、同時に使用すると危険なものは使用しないように細心の注意を払います。運用環境では、主キー違反や行の重複が非常に簡単に発生します。