A qualquer momento no passado, se alguém tivesse me perguntado o tamanho máximo para um varchar(max)
, eu teria dito que 2 GB, ou olhou para uma forma mais exata figura (2 ^ 31-1, ou 2147483647).
No entanto, em alguns testes recentes, descobri que as varchar(max)
variáveis podem aparentemente exceder este tamanho:
create table T (
Val1 varchar(max) not null
)
go
declare @KMsg varchar(max) = REPLICATE('a',1024);
declare @MMsg varchar(max) = REPLICATE(@KMsg,1024);
declare @GMsg varchar(max) = REPLICATE(@MMsg,1024);
declare @GGMMsg varchar(max) = @GMsg + @GMsg + @MMsg;
select LEN(@GGMMsg)
insert into T(Val1) select @GGMMsg
select LEN(Val1) from T
Resultados:
(no column name)
2148532224
(1 row(s) affected)
Msg 7119, Level 16, State 1, Line 6
Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
The statement has been terminated.
(no column name)
(0 row(s) affected)
Portanto, como agora sei que uma variável pode exceder a barreira de 2 GB - alguém sabe qual é o limite real de uma varchar(max)
variável?
(Teste acima concluído no SQL Server 2008 (não R2). Gostaria de saber se ele se aplica a outras versões)
sql-server
tsql
Damien_The_Unbeliever
fonte
fonte
declare @x varchar(max) = 'XX'; SELECT LEN(REPLICATE(@x,2147483647))
dá4294967294
para mim, mas leva muito tempo para ser executado - mesmo depois que oSELECT
voltou, não tenho certeza do que esse tempo extra é gasto fazendo.Respostas:
Tanto quanto posso dizer, não há limite máximo em 2008.
No SQL Server 2005, o código em sua pergunta falha na atribuição à
@GGMMsg
variável como código abaixo falha com
No entanto, parece que essas limitações foram discretamente levantadas. Em 2008
Devoluções
Eu executei isso na minha máquina de desktop de 32 bits, então essa string de 8 GB é muito mais do que memória endereçável
Corrida
Retornou
então presumo que tudo isso seja armazenado em
LOB
páginastempdb
sem validação de comprimento. O crescimento da contagem de páginas estava associado àSET @y = REPLICATE(@y,92681);
declaração. A atribuição inicial da variável@y
e oLEN
cálculo não aumentaram isso.A razão para mencionar isso é porque a contagem de páginas é muito maior do que eu esperava. Supondo uma página de 8 KB, isso resulta em 16,36 GB, o que é obviamente mais ou menos o dobro do que seria necessário. Eu especulo que isso provavelmente se deve à ineficiência da operação de concatenação de string, que precisa copiar toda a string enorme e anexar um pedaço ao final, em vez de ser capaz de adicionar ao final da string existente. Infelizmente, no momento, o
.WRITE
método não é compatível com variáveis varchar (max).Adição
Também testei o comportamento com concatenação
nvarchar(max) + nvarchar(max)
envarchar(max) + varchar(max)
. Ambos permitem que o limite de 2 GB seja excedido. A tentativa de armazenar os resultados disso em uma tabela falha, porém com a mensagem de erroAttempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
novamente. O script para isso está abaixo (pode levar muito tempo para ser executado).fonte
varchar
valores maiores que 8.000 caracteres em cadeias literais no código, contanto que você não tentasse colocá-lo em uma variável ouvarchar
coluna.EDIT : Após uma investigação mais aprofundada, minha suposição original de que esta era uma anomalia (bug?) Da
declare @var datatype = value
sintaxe está incorreta.Modifiquei seu script para 2005, pois essa sintaxe não é compatível e tentei a versão modificada em 2008. Em 2005, recebo a
Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
mensagem de erro. Em 2008, o script modificado ainda é bem-sucedido.fonte
Attempting to grow...
erro naset @GGMMsg=...
declaração. Em 2008, o roteiro é um sucesso.