web-dev-qa-db-ja.com

SQL Server / T-SQLは長い文字列を分割するために行継続をサポートしていますか?

時々、1つ以上の非常に長い(時には愚かな長い)文字列を含むSQLスクリプトがあります。通常、これらはファイル/アセンブリを表すVARBINARYリテラル/定数ですが、テキストの場合もあります。

本当に長い文字列の主な問題は、一部のテキストエディターがそれらをうまく処理できないことです。たとえば、私はCREATE Assembly [AssemblyName] FROM 0x....ステートメントで使用するVARBINARYリテラルを持っています。アセンブリ自体のサイズは1 MBをわずかに超えています。各バイトは、16進表記で表される2つの文字を必要とします(たとえば、0x1F = a 1およびF)。 SQL Server Management Studio(SSMS)はこれをうまく処理せず、その行をスクロールしようとすると数秒間ハングします。実際、一部のバージョン(これが発生するかどうかは不明)では、特定の長さの行が少なくとも1行あるスクリプトを開くと、長い行に関する警告さえ表示されます。

2番目の問題は、ワードラップを有効にせずにエディターで使用したり、オンラインで投稿したりすると、フォーマットが複雑になることです。ここでの問題は、水平スクロールバーのスライダーが非常に狭く、少しでも移動すると、非超長のテキストが表示されないようにスクロールすることです。

現在、T-SQLはコマンドを改行またはセミコロンで終了しません(SQL Server 2005以降、セミコロンが推奨/推奨されています)。したがって、SQL Serverは各ステートメントを解析する方法を知っているので、いつ終了するかがわかるので、長い行を複数の行に分割し、 newline / carriage-return + line-feed、無理はないようです。しかし、これはどちらの場合でも機能しません。

PRINT 'Line1
Line2';

戻り値([メッセージ]タブ):

Line1
Line2

そして、改行はリテラル/定数の中にあるので、それは十分に理にかなっています。しかし、これをVARBINARYに対して行うこともできません。

PRINT 0x1234
5678;

エラーが出ます。

13
Solomon Rutzky

ありがたいことに、T-SQLの行継続のサポートがあります。 \ (バックスラッシュ)文字。行の終わりの直前に配置します newline / carriage-return + line-feed、および改行は無視されます。

テキスト文字列の場合、これは次のように動作します。

PRINT 'Line1\
Line2';

戻り値([メッセージ]タブ):

Line1Line2

バイナリ/ 16進数文字列の場合、これは次のように動作します。

PRINT 0x1234\
5678;

戻り値([メッセージ]タブ):

0x12345678;

SQLスクリプトで使用するためにバイナリファイル(アセンブリ、証明書)をテキストの16バイト文字列にフォーマットするために、GitHubでオープンソースとしてリリースした BinaryFormatter というコマンドラインユーティリティを作成しました。バイナリファイルをテキスト表現に変換するだけでなく、行継続を使用して、長いVARBINARYリテラルを、各行に使用する指定された文字数に基づいて、必要な数の行に分散します。結果は次のようになります。

4D5A09DE34F178313345A4\
00007F4E39782EFC48D842\
00000000

次に、以下の{...}エリアに示すように、それをコピーしてスクリプトに貼り付けます。

CREATE Assembly [AssemblyName]
FROM 0x\
{output from BinaryFormatter}
;

このトピックの詳細については、私のブログ投稿を参照してください: T-SQLのLine-Continuation

13
Solomon Rutzky