Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Tamanho máximo de uma variável varchar(max)


Tanto quanto posso dizer, não há limite superior em 2008.

No SQL Server 2005, o código em sua pergunta falha na atribuição ao @GGMMsg variável com

Tentativa de aumentar o LOB além do tamanho máximo permitido de 2.147.483.647 bytes.

o código abaixo falha com

REPLICATE:O comprimento do resultado excede o limite de comprimento (2 GB) do tipo grande de destino.

No entanto, parece que essas limitações foram discretamente levantadas. Em 2008
DECLARE @y VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),92681); 

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

SELECT LEN(@y) 

Devoluções
8589767761

Eu executei isso na minha máquina desktop de 32 bits, então essa string de 8 GB é muito superior à memória endereçável

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

Devolvida
internal_objects_alloc_page_co 
------------------------------ 
2144456    

então presumo que tudo isso seja armazenado em LOB páginas em tempdb sem validação de comprimento. O crescimento da contagem de páginas foi associado ao SET @y = REPLICATE(@y,92681); demonstração. A atribuição de variável inicial para @y e o LEN cálculo não aumentou isso.

A razão para mencionar isso é porque a contagem de páginas é muito maior do que eu esperava. Assumindo uma página de 8 KB, isso funciona em 16,36 GB, o que obviamente é mais ou menos o dobro do que parece ser necessário. Eu especulo que isso é provavelmente devido à ineficiência da operação de concatenação de strings que precisa copiar toda a string enorme e anexar um pedaço ao final, em vez de poder adicionar ao final da string existente. Infelizmente no momento o .WRITE O método não tem suporte para variáveis ​​varchar(max).

Adição

Também testei o comportamento com a concatenação de nvarchar(max) + nvarchar(max) e nvarchar(max) + varchar(max) . Ambos permitem que o limite de 2 GB seja excedido. Tentar armazenar os resultados disso em uma tabela falha, no entanto, com a mensagem de erro Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes. novamente. O script para isso está abaixo (pode levar muito tempo para ser executado).
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