読者です 読者をやめる 読者になる 読者になる

T-SQL FORMATMESSAGE の機能強化

SQL Server 2016 で強化された T-SQL で、開発時にクエリ書く人が使いそうなのをピックアップして取り上げてみようと思います。

SQL Server 2016 RC3 から FORMATMESSAGE が引数に、メッセージ番号だけではなく任意の文字列を受け取れるようになりました。
FORMATMESSAGE (Transact-SQL)

FORMATMESSAGE が元々どういうものかと言うと

SELECT text FROM sys.messages WHERE message_id = 20009 AND language_id = 1033;
DECLARE @var1 VARCHAR(200); 
SELECT @var1 = FORMATMESSAGE(20009, 'First Variable', 'Second Variable'); 
SELECT @var1; -- The article 'First Variable' could not be added to the publication 'Second Variable'.

こんな感じのやつです。
sys.messages の message_id を渡して、文字列を作成するってやつです。
これが message_id ではなく、任意の文字列を受け取れるようになりました。
メッセージの文字列は、RAISERROR (Transact-SQL) の msg_str と同じ制限があります。
例えば上と同じ結果を返そうとすると以下のクエリになります。

select FORMATMESSAGE('The article ''%s'' could not be added to the publication ''%s''.', 'First Variable', 'Second Variable');

String.Format メソッド (String, Object[]) (System) のような感じで使えます。
sys.messages 関係無く使えるので、別の関数名で新しく作っても良かったのでは?と思いましたが、
この機能アンドキュメントなだけで、2016 より前のバージョンでも使えました。
検証のため全部同じクエリで試しています。

SQL Server 2016

ドキュメント通り使えます。

SQL Database v12

SQL DB はまあ使えて当然な感じ。

SQL Server 2014

2014 でも使えますね~。

SQL Server 2012

なんと 2012 でも使えます。

SQL Server 2008

さすがに 2008 は無理でした。


というわけで、2012 以降から使えそうですね。
もともと使えてたから、関数名も変えずにそのままでってところなんでしょうか。
引数は、文字列リテラルに限らずテーブルの列やサブクエリも書けるので自前のメッセージテーブルから使うことも出来ます。

例:sys.messages を自前のメッセージテーブルと思ってください。

select FORMATMESSAGE( 
  (SELECT text FROM sys.messages WHERE message_id = 20009 AND language_id = 1033)
  , 'First Variable'
  , 'Second Variable'
)

select FORMATMESSAGE(text, 'First Variable'  , 'Second Variable') FROM sys.messages