関連するハード コードされた制限はありません (65,536 * 4 KB のネットワーク パケット サイズは 268 MB であり、スクリプトの長さはそれに近いものではありません) が、大量の行に対してこの方法を使用することはお勧めできません。
表示されているエラーは、SQL Server ではなくクライアント ツールによってスローされます。動的 SQL コンパイルで SQL 文字列を構築すると、少なくとも正常に開始できます
DECLARE @SQL NVARCHAR(MAX) = '(100,200,300),
';
SELECT @SQL = 'SELECT * FROM (VALUES ' + REPLICATE(@SQL, 1000000) + '
(100,200,300)) tc (proj_d, period_sid, val)';
SELECT @SQL AS [processing-instruction(x)]
FOR XML PATH('')
SELECT DATALENGTH(@SQL) / 1048576.0 AS [Length in MB] --30.517705917
EXEC(@SQL);
〜30分のコンパイル時間後に上記を殺しましたが、それでも行は生成されませんでした。リテラル値は、プラン自体の中に定数のテーブルとして格納する必要があり、SQL Server は 多くの時間 それらについてのプロパティも導出しようとしています。
SSMS は 32 ビット アプリケーションであり、std::bad_alloc
をスローします。 バッチの解析中の例外
容量に達した Token のベクトルに要素をプッシュしようとしましたが、十分な大きさの連続したメモリ領域が利用できないため、サイズ変更の試みは失敗しました。したがって、ステートメントはサーバーに到達することさえありません。
ベクター容量は毎回 50% ずつ増加します (つまり、こちらのシーケンス に従います)。 )。ベクトルが拡張する必要がある容量は、コードのレイアウト方法によって異なります。
以下は、容量を 19 から 28 に増やす必要があります。
SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val)
以下は 2 のサイズのみを必要とします
SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val)
以下は> 63 かつ <=94 の容量を必要とします。
SELECT *
FROM (VALUES
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300),
(100,
200,
300)
) tc (proj_d, period_sid, val)
ケース 1 のようにレイアウトされた 100 万行の場合、ベクトル容量は 3,543,306 に増加する必要があります。
次のいずれかによって、クライアント側の解析が成功することがわかる場合があります。
<オール>ただし、サーバーへの送信に成功したとしても、上記で説明したように、実行計画の生成中にサーバーを強制終了するだけです。
インポート エクスポート ウィザードを使用してテーブルをロードする方がはるかに優れています。 TSQL で実行する必要がある場合は、小さなバッチに分割したり、XML の細断処理などの別の方法を使用したりすると、テーブル値コンストラクターよりもパフォーマンスが向上します。たとえば、次のコードは私のマシンで 13 秒で実行されます (ただし、SSMS を使用している場合は、大量の XML 文字列リテラルを貼り付けるのではなく、複数のバッチに分割する必要があります)。
DECLARE @S NVARCHAR(MAX) = '<x proj_d="100" period_sid="200" val="300" />
' ;
DECLARE @Xml XML = REPLICATE(@S,1000000);
SELECT
x.value('@proj_d','int'),
x.value('@period_sid','int'),
x.value('@val','int')
FROM @Xml.nodes('/x') c(x)