メモ:T-SQL OUTPUT 句使ったときに INTO 付けてないと TRIGGER あったら怒られる

OUTPUT 句 (Transact-SQL) - SQL Server | Microsoft Docs

トリガー 使ってたら怒られたのでドキュメントのメモ。

INTO キーワードを指定せずに OUTPUT 句を指定すると、DML 操作を行った先では、その DML アクションに対して定義されたトリガーを有効化できません。 たとえば、UPDATE ステートメント内で OUTPUT 句が定義されていると、対象のテーブルで UPDATE トリガーを有効化できません。

ほかにも注意点は、トリガーが実行される前のデータを返すって。

OUTPUT から返される列は、INSERT ステートメント、UPDATE ステートメント、または DELETE ステートメントが完了した後、トリガーが実行される前のデータを反映します。

今回はトリガーで自身のテーブル更新しないんで関係ないけど。
てか、トリガー実行前なら、INTO 無しでも返してくれてもいーのに。

コード例:面倒なので GitHub - DapperLib/Dapper: Dapper - a simple object mapper for .Net を使う前提で書いてます。

using var conn = new SqlConnection("~");
var id = await conn.ExecuteScalarAsync(
  "insert into [Table1] (~) output [inserted].[Id] values (~)"
  , new {~});

これがエラーになるので、こんな感じに書き換え。

using var conn = new SqlConnection("~");
var id = await conn.ExecuteScalarAsync(
  @"declare @t table (Id bigint not null);
insert into [Table1] (~) output [inserted].[Id] into @t values (~);
select * from @t;"
  , new {~});

テーブルの定義は OUTPUT で返す列を定義してください。
若干面倒だけど多分これが一番マシ。*1

トリガーで自身を更新してかつ timestamp あると大変だねーって投稿:
sql - Cannot use UPDATE with OUTPUT clause when a trigger is on the table - Stack Overflow

そもそも timestamp 関係なくトリガーで自身を更新するなら OUTPUT は使わんほうが良さげ。

*1:複文サポートされててよかったね