O ile wiem, w 2008 roku nie ma górnego limitu.
W SQL Server 2005 kod w twoim pytaniu kończy się niepowodzeniem przy przypisaniu do @GGMMsg
zmienna z
Próba zwiększenia LOB poza maksymalny dozwolony rozmiar 2 147 483 647 bajtów.
poniższy kod nie powiedzie się z
REPLICATE:Długość wyniku przekracza limit długości (2 GB) docelowego typu dużego.
Wydaje się jednak, że te ograniczenia zostały po cichu zniesione. W 2008
DECLARE @y VARCHAR(MAX) = REPLICATE(CAST('X' AS VARCHAR(MAX)),92681);
SET @y = REPLICATE(@y,92681);
SELECT LEN(@y)
Zwroty
8589767761
Uruchomiłem to na moim 32-bitowym komputerze stacjonarnym, więc ten ciąg 8 GB to znacznie więcej pamięci adresowalnej
Bieganie
select internal_objects_alloc_page_count
from sys.dm_db_task_space_usage
WHERE session_id = @@spid
Zwrócone
internal_objects_alloc_page_co
------------------------------
2144456
więc zakładam, że to wszystko zostanie zapisane w LOB
strony w tempdb
bez weryfikacji długości. Wzrost liczby stron był powiązany z SET @y = REPLICATE(@y,92681);
oświadczenie. Początkowe przypisanie zmiennej do @y
i LEN
obliczenia nie zwiększyły tego.
Powodem, dla którego o tym wspominam, jest to, że liczba stron jest znacznie większa, niż się spodziewałem. Zakładając, że strona 8 KB, to daje to 16,36 GB, co oczywiście jest mniej więcej dwa razy większe niż wydaje się konieczne. Spekuluję, że jest to prawdopodobnie spowodowane nieefektywnością operacji łączenia ciągów, która wymaga skopiowania całego ogromnego ciągu i dodania kawałka na końcu, zamiast możliwości dodania go na końcu istniejącego ciągu. Niestety w tej chwili .WRITE
metoda nie jest obsługiwana dla zmiennych varchar(max).
Dodanie
Testowałem również zachowanie za pomocą łączenia nvarchar(max) + nvarchar(max)
i nvarchar(max) + varchar(max)
. Oba pozwalają na przekroczenie limitu 2 GB. Próba zapisania wyników tego w tabeli kończy się jednak niepowodzeniem z komunikatem o błędzie Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
ponownie. Skrypt do tego znajduje się poniżej (uruchomienie może zająć dużo czasu).
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