Доколкото мога да кажа, няма горна граница през 2008 г.
В SQL Server 2005 кодът във вашия въпрос е неуспешен при присвояването на @GGMMsg
променлива с
Опит за увеличаване на LOB над максималния разрешен размер от 2 147 483 647 байта.
кодът по-долу не работи с
РЕПЛИЦИРАНЕ:Дължината на резултата надвишава ограничението за дължина (2GB) на целевия голям тип.
Изглежда обаче, че тези ограничения тихомълком са премахнати. През 2008 г.
DECLARE @y VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),92681);
SET @y = REPLICATE(@y,92681);
SELECT LEN(@y)
Връща
8589767761
Пуснах това на моята 32-битова настолна машина, така че този низ от 8 GB е доста повече от адресируемата памет
Работи
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)
. И двете позволяват превишаване на ограничението от 2GB. Опитът след това да съхрани резултатите от това в таблица, след това се проваля със съобщението за грешка 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