sql >> Database >  >> RDS >> Sqlserver

Maximale grootte van een varchar(max) variabele

Voor zover ik weet is er geen bovengrens in 2008.

In SQL Server 2005 mislukt de code in uw vraag bij de toewijzing aan de @GGMMsg variabele met

Poging om LOB groter te maken dan de maximaal toegestane grootte van 2.147.483.647bytes.

de onderstaande code mislukt met

REPLICATE:De lengte van het resultaat overschrijdt de lengtelimiet (2GB) van het grote doeltype.

Het lijkt er echter op dat deze beperkingen stilletjes zijn opgeheven. Op 2008

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

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

SELECT LEN(@y) 

Retourneren

8589767761

Ik heb dit op mijn 32-bits desktopcomputer uitgevoerd, dus deze string van 8 GB is veel meer dan het adresseerbare geheugen

Hardlopen

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

Geretourneerd

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

dus ik neem aan dat dit allemaal gewoon wordt opgeslagen in LOB pagina's in tempdb zonder validatie op lengte. De groei van het aantal pagina's was allemaal gekoppeld aan de SET @y = REPLICATE(@y,92681); uitspraak. De initiële variabele toewijzing aan @y en de LEN berekening heeft dit niet verhoogd.

De reden om dit te vermelden is omdat het aantal pagina's enorm hoger is dan ik had verwacht. Uitgaande van een pagina van 8 KB, komt dit uit op 16,36 GB, wat duidelijk min of meer het dubbele is van wat nodig lijkt. Ik speculeer dat dit waarschijnlijk te wijten is aan de inefficiëntie van de aaneenschakeling van strings, waarbij de hele enorme string moet worden gekopieerd en een stuk aan het einde moet worden toegevoegd in plaats van aan het einde van de bestaande string te kunnen toevoegen. Helaas is op dit moment de .WRITE methode wordt niet ondersteund voor varchar(max) variabelen.

Toevoeging

Ik heb het gedrag ook getest met het aaneenschakelen van nvarchar(max) + nvarchar(max) en nvarchar(max) + varchar(max) . Met beide kan de limiet van 2 GB worden overschreden. Proberen om de resultaten hiervan vervolgens op te slaan in een tabel mislukt echter met de foutmelding Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes. nog een keer. Het script daarvoor staat hieronder (kan lang duren om uit te voeren).

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. Een ORA 028513 DG4ODBC-fout onderzoeken

  2. MariaDB JSON_TYPE() uitgelegd

  3. MySQL JDBC-stuurprogramma's installeren in Pentaho Data Integration en BA Server-tools

  4. Opgeslagen T-SQL-procedure die meerdere id-waarden accepteert