sql >> データベース >  >> RDS >> Sqlserver

varchar(max)変数の最大サイズ

    私の知る限り、2008年には上限はありません。

    SQL Server 2005では、質問のコードは@GGMMsgへの割り当てで失敗します 変数付き

    最大許容サイズの2,147,483,647バイトを超えてLOBを拡張しようとしています。

    以下のコードは

    で失敗します

    REPLICATE:結果の長さがターゲットのラージタイプの長さ制限(2GB)を超えています。

    ただし、これらの制限は静かに解除されたようです。 2008年

    DECLARE @y VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),92681); 
    
    SET @y = REPLICATE(@y,92681);
    
    SELECT LEN(@y) 
    

    返品

    8589767761
    

    これを32ビットデスクトップマシンで実行したので、この8GBの文字列はアドレス可能なメモリをはるかに超えています

    実行中

    select internal_objects_alloc_page_count
    from sys.dm_db_task_space_usage
    WHERE session_id = @@spid
    

    返品

    internal_objects_alloc_page_co 
    ------------------------------ 
    2144456    
    

    したがって、これはすべてLOBに格納されるだけだと思います tempdbのページ 長さの検証なし。ページ数の増加はすべて、SET @y = REPLICATE(@y,92681);に関連していました。 声明。 @yへの最初の変数の割り当て およびLEN 計算はこれを増加させませんでした。

    これに言及する理由は、ページ数が私が予想していたよりもはるかに多いためです。 8KBのページを想定すると、これは16.36 GBで機能します。これは、明らかに必要と思われる値の2倍です。これは、既存の文字列の最後に追加するのではなく、巨大な文字列全体をコピーして最後にチャンクを追加する必要がある文字列連結操作の非効率性が原因である可能性が高いと推測されます。残念ながら、現時点では.WRITE メソッドはvarchar(max)変数ではサポートされていません。

    追加

    また、nvarchar(max) + nvarchar(max)を連結して動作をテストしました。 およびnvarchar(max) + varchar(max) 。これらは両方とも、2GBの制限を超えることができます。次に、この結果をテーブルに保存しようとすると失敗しますが、エラーメッセージAttempting to grow LOB beyond maximum allowed size of 2147483647 bytes. また。そのためのスクリプトは以下のとおりです(実行に時間がかかる場合があります)。

    DECLARE @y1 VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),2147483647); 
    SET @y1 = @y1 + @y1;
    SELECT LEN(@y1), DATALENGTH(@y1)  /*4294967294, 4294967292*/
    
    
    DECLARE @y2 NVARCHAR(MAX) = REPLICATE(CAST('X' AS NVARCHAR(MAX)),1073741823); 
    SET @y2 = @y2 + @y2;
    SELECT LEN(@y2), DATALENGTH(@y2)  /*2147483646, 4294967292*/
    
    
    DECLARE @y3 NVARCHAR(MAX) = @y2 + @y1
    SELECT LEN(@y3), DATALENGTH(@y3)   /*6442450940, 12884901880*/
    
    /*This attempt fails*/
    SELECT @y1 y1, @y2 y2, @y3 y3
    INTO Test
    


    1. PostgreSQLのパターンマッチングとは異なるパターンマッチングの使用中にエラーが発生しました

    2. java.lang.OutOfMemoryError:SqliteAndroidからデータを読み取っているときに[メモリが使い果たされました]

    3. MySQLの日付形式のチートシート

    4. Oracle SQLエスケープ文字(「&」の場合)