sql >> Databasteknik >  >> RDS >> Sqlserver

Maximal storlek för en varchar(max)-variabel

Såvitt jag kan säga finns det ingen övre gräns för 2008.

I SQL Server 2005 misslyckas koden i din fråga i tilldelningen till @GGMMsg variabel med

Försöker öka LOB utöver den maximala tillåtna storleken på 2 147 483 647 byte.

koden nedan misslyckas med

REPLICATE:Längden på resultatet överskrider längdgränsen (2 GB) för den stora måltypen.

Men det verkar som om dessa begränsningar tyst har hävts. 2008

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

SET @y = REPLICATE(@y,92681);

SELECT LEN(@y) 

Retur

8589767761

Jag körde detta på min 32-bitars stationära dator så den här 8GB-strängen är långt över adresserbart minne

Körs

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

Returnerade

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

så jag antar att allt detta bara lagras i LOB sidor i tempdb utan validering av längden. Tillväxten av sidantal var all associerad med SET @y = REPLICATE(@y,92681); påstående. Den initiala variabeltilldelningen till @y och LEN beräkning ökade inte detta.

Anledningen till att nämna detta är för att sidantalet är enormt mer än jag förväntade mig. Om man antar en 8KB-sida så fungerar detta på 16,36 GB vilket uppenbarligen är mer eller mindre dubbelt vad som verkar vara nödvändigt. Jag spekulerar i att detta sannolikt beror på ineffektiviteten i strängsammansättningsoperationen som behöver kopiera hela den enorma strängen och lägga till en bit på slutet istället för att kunna lägga till i slutet av den befintliga strängen. Tyvärr för närvarande .WRITE Metoden stöds inte för varchar(max)-variabler.

Tillägg

Jag har också testat beteendet med att sammanfoga nvarchar(max) + nvarchar(max) och nvarchar(max) + varchar(max) . Båda dessa tillåter att gränsen på 2 GB överskrids. Att sedan försöka lagra resultaten av detta i en tabell misslyckas dock med felmeddelandet Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes. på nytt. Skriptet för det är nedan (kan ta lång tid att köra).

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. INTE I urval med NULL-värden

  2. Hur formaterar man bigint-fält till ett datum i Postgresql?

  3. Kriterier för viloläge för datum

  4. MySQL - hur många rader kan jag infoga i en enda INSERT-sats?