sql >> Base de Datos >  >> RDS >> Sqlserver

Tamaño máximo de una variable varchar (max)

Que yo sepa, no hay un límite superior en 2008.

En SQL Server 2005, el código de su pregunta falla en la asignación a @GGMMsg variable con

Intentando hacer crecer el LOB más allá del tamaño máximo permitido de 2 147 483 647 bytes.

el siguiente código falla con

REPLICAR:La longitud del resultado supera el límite de longitud (2 GB) del tipo de destino grande.

Sin embargo, parece que estas limitaciones se han eliminado silenciosamente. En 2008

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

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

SELECT LEN(@y) 

Devoluciones

8589767761

Ejecuté esto en mi máquina de escritorio de 32 bits, por lo que esta cadena de 8 GB supera con creces la memoria direccionable

Corriendo

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

Devuelto

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

así que supongo que todo esto se almacena en LOB páginas en tempdb sin validación de longitud. El crecimiento del número de páginas se asoció con SET @y = REPLICATE(@y,92681); declaración. La asignación de variable inicial a @y y el LEN el cálculo no aumentó esto.

La razón para mencionar esto es que el número de páginas es mucho mayor de lo que esperaba. Suponiendo una página de 8 KB, esto da como resultado 16,36 GB, que obviamente es más o menos el doble de lo que parece ser necesario. Especulo que esto probablemente se deba a la ineficiencia de la operación de concatenación de cadenas que necesita copiar toda la cadena enorme y agregar un fragmento al final en lugar de poder agregar al final de la cadena existente. Desafortunadamente, en este momento el .WRITE El método no es compatible con las variables varchar(max).

Adición

También probé el comportamiento concatenando nvarchar(max) + nvarchar(max) y nvarchar(max) + varchar(max) . Ambos permiten superar el límite de 2 GB. Sin embargo, intentar almacenar los resultados de esto en una tabla falla con el mensaje de error Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes. otra vez. El script para eso se encuentra a continuación (puede tardar mucho tiempo en ejecutarse).

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