Насколько я могу судить, в 2008 году не было верхнего предела.
В SQL Server 2005 ваш код не выполняется при назначении переменной @GGMMsg
с
Попытка увеличить LOB за максимально допустимый размер в 2 147 483 647 байт.
приведенный ниже код завершается с
REPLICATE: длина результата превышает ограничение длины (2 ГБ) целевого большого типа.
Однако, похоже, эти ограничения были незаметно сняты.В 2008
DECLARE @y VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),92681);
SET @y = REPLICATE(@y,92681);
SELECT LEN(@y)
Возвращает
8589767761
Я запустил это на своем 32-битном настольном компьютере, так что эта строка 8 ГБ намного превышает адресную память
Работает
select internal_objects_alloc_page_count
from sys.dm_db_task_space_usage
WHERE session_id = @@spid
Возвращено
internal_objects_alloc_page_co
------------------------------
2144456
, поэтому я предполагаю, что все это просто сохраняется в LOB
страницах в tempdb
без проверки длины.Увеличение количества страниц было связано с оператором SET @y = REPLICATE(@y,92681);
.Первоначальное присвоение переменной @y
и расчет LEN
не увеличили это.
Причина упоминания этого заключается в том, что количество страниц намного больше, чем я ожидал.Если предположить, что страница размером 8 КБ, то получается 16,36 ГБ, что, очевидно, более или менее вдвое больше, чем кажется необходимым.Я предполагаю, что это, скорее всего, связано с неэффективностью операции конкатенации строк, которая требует копирования всей огромной строки и добавления фрагмента в конец, а не возможности добавления в конец существующей строки.К сожалению, на данный момент .WRITE
метод не поддерживается для переменных varchar (max).
Добавление
Я также тестировалповедение с конкатенацией nvarchar(max) + nvarchar(max)
и nvarchar(max) + varchar(max)
.Оба из них позволяют превышать ограничение в 2 ГБ.Попытка затем сохранить результаты этого в таблице тогда терпит неудачу с сообщением об ошибке Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
снова.Сценарий для этого ниже (может занять много времени).
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