Наскільки я можу зрозуміти, у 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)
DECLARE @y2 NVARCHAR(MAX) = REPLICATE(CAST('X' AS NVARCHAR(MAX)),1073741823);
SET @y2 = @y2 + @y2;
SELECT LEN(@y2), DATALENGTH(@y2)
DECLARE @y3 NVARCHAR(MAX) = @y2 + @y1
SELECT LEN(@y3), DATALENGTH(@y3)
SELECT @y1 y1, @y2 y2, @y3 y3
INTO Test
declare @x varchar(max) = 'XX'; SELECT LEN(REPLICATE(@x,2147483647))
дає4294967294
для мене, але працює багато часу - навіть після того,SELECT
як повернувся, тому не знаю, на що витрачається зайвий час.