At any time in the past, if someone had asked me the maximum size for a varchar(max), I’d have said 2GB, or looked up a more exact figure (2^31-1, or 2147483647).
However, in some recent testing, I discovered that varchar(max) variables can apparently exceed this size:
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
Results:
(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)
So, given that I now know that a variable can exceed the 2GB barrier – does anyone know what the actual limit is for a varchar(max) variable?
(Above test completed on SQL Server 2008 (not R2). I’d be interested to know whether it applies to other versions)
As far as I can tell there is no upper limit in 2008.
In SQL Server 2005 the code in your question fails on the assignment to the
@GGMMsgvariable withthe code below fails with
However it appears these limitations have quietly been lifted. On 2008
Returns
I ran this on my 32 bit desktop machine so this 8GB string is way in excess of addressable memory
Running
Returned
so I presume this all just gets stored in
LOBpages intempdbwith no validation on length. The page count growth was all associated with theSET @y = REPLICATE(@y,92681);statement. The initial variable assignment to@yand theLENcalculation did not increase this.The reason for mentioning this is because the page count is hugely more than I was expecting. Assuming an 8KB page then this works out at 16.36 GB which is obviously more or less double what would seem to be necessary. I speculate that this is likely due to the inefficiency of the string concatenation operation needing to copy the entire huge string and append a chunk on to the end rather than being able to add to the end of the existing string. Unfortunately at the moment the
.WRITEmethod isn’t supported for varchar(max) variables.Paul White confirms the above supposition here and also provides the information that the variable is held entirely in memory if <= 512KB and changes to the tempdb-based backup scheme for values larger than that.
Addition
I’ve also tested the behaviour with concatenating
nvarchar(max) + nvarchar(max)andnvarchar(max) + varchar(max). Both of these allow the 2GB limit to be exceeded. Trying to then store the results of this in a table then fails however with the error messageAttempting to grow LOB beyond maximum allowed size of 2147483647 bytes.again. The script for that is below (may take a long time to run).