1. ホーム
  2. sql

[解決済み】SQL Server 存在しない場合に挿入する。

2022-03-26 06:49:13

質問

テーブルにデータを挿入したいのですが、データベースにまだ存在しないデータのみを挿入したいのです。

以下は私のコードです。

ALTER PROCEDURE [dbo].[EmailsRecebidosInsert]
  (@_DE nvarchar(50),
   @_ASSUNTO nvarchar(50),
   @_DATA nvarchar(30) )
AS
BEGIN
   INSERT INTO EmailsRecebidos (De, Assunto, Data)
   VALUES (@_DE, @_ASSUNTO, @_DATA)
   WHERE NOT EXISTS ( SELECT * FROM EmailsRecebidos 
                   WHERE De = @_DE
                   AND Assunto = @_ASSUNTO
                   AND Data = @_DATA);
END

そして、そのエラーは

Msg 156, Level 15, State 1, Procedure EmailsRecebidosInsert, Line 11

キーワード 'WHERE' 付近の構文が正しくありません。

どのように解決するのですか?

以下のコードの代わりに

BEGIN
   INSERT INTO EmailsRecebidos (De, Assunto, Data)
   VALUES (@_DE, @_ASSUNTO, @_DATA)
   WHERE NOT EXISTS ( SELECT * FROM EmailsRecebidos 
                   WHERE De = @_DE
                   AND Assunto = @_ASSUNTO
                   AND Data = @_DATA);
END

に置き換えます。

BEGIN
   IF NOT EXISTS (SELECT * FROM EmailsRecebidos 
                   WHERE De = @_DE
                   AND Assunto = @_ASSUNTO
                   AND Data = @_DATA)
   BEGIN
       INSERT INTO EmailsRecebidos (De, Assunto, Data)
       VALUES (@_DE, @_ASSUNTO, @_DATA)
   END
END

更新されました。 (ご指摘いただいた @Marc Durdin 氏に感謝します)

高負荷の場合、これはまだ失敗することがあります。2番目の接続が、最初の接続がINSERTを実行する前にIF NOT EXISTSテストをパスすることができるからです。つまり競合状態です。 stackoverflow.com/a/3791506/1836776 トランザクションでラップしても解決しない理由については、良い答えがあります。