Максимальный размер переменной varchar(max)
в любое время в прошлом, если бы кто-то спросил меня максимальный размер varchar(max), Я бы сказал 2GB, или посмотрел более точно рисунок (2^31-1, или 2147483647).
однако, в некоторых недавних испытаниях, я обнаружил, что varchar(max) переменные, по-видимому, могут превышать этот размер:
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
результаты:
(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)
Итак, учитывая, что я теперь знаю, что a переменная может превышать барьер 2 ГБ - кто-нибудь знает, что фактический предел это для varchar(max) переменной?
(выше тест завершен на SQL Server 2008 (не R2). Мне было бы интересно узнать, относится ли это к другим версиям)
3 ответов:
насколько я могу судить, в 2008 году нет верхнего предела.
в SQL Server 2005 код в вашем вопросе терпит неудачу при присвоении
@GGMMsgпеременной спопытка увеличить лоб сверх максимально допустимого размера 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-битном настольном компьютере, так что эта строка 8GB намного превышает адресную память
под управлением
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расчет не увеличил это.причина упоминания об этом заключается в том, что количество страниц намного больше, чем я ожидал. Предполагая, что страница 8KB тогда это работает на 16.36 GB, что, очевидно, более или менее вдвое больше того, что, казалось бы, необходимо. Я предполагаю, что это, вероятно, связано с неэффективностью операции конкатенации строк, необходимой для копирования всего огромная строка и добавить кусок на конец, а не быть в состоянии добавить в конец существующей строки. К сожалению, на данный момент
.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
EDIT: после дальнейшего расследования, мое первоначальное предположение, что это была аномалия (ошибка?) из
declare @var datatype = valueсинтаксис неправильный.Я изменил ваш скрипт на 2005 год, так как этот синтаксис не поддерживается, а затем попробовал измененную версию на 2008 год. В 2005 году я получаю
Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.сообщение об ошибке. В 2008 году измененный сценарий все еще успешен.declare @KMsg varchar(max); set @KMsg = REPLICATE('a',1024); declare @MMsg varchar(max); set @MMsg = REPLICATE(@KMsg,1024); declare @GMsg varchar(max); set @GMsg = REPLICATE(@MMsg,1024); declare @GGMMsg varchar(max); set @GGMMsg = @GMsg + @GMsg + @MMsg; select LEN(@GGMMsg)
Comments