O ile wiem, w 2008 roku nie ma górnej granicy.
W SQL Server 2005 kod w twoim pytaniu nie powiedzie się przy przypisaniu do @GGMMsg
zmiennej z
Próba zwiększenia LOB poza maksymalny dozwolony rozmiar 2 147 483 647 bajtów.
poniższy kod nie działa
REPLICATE: długość wyniku przekracza limit długości (2 GB) docelowego dużego typu.
Jednak wydaje się, że ograniczenia te zostały po cichu zniesione. W 2008r
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 jest znacznie większy niż pamięć adresowalna
Bieganie
select internal_objects_alloc_page_count
from sys.dm_db_task_space_usage
WHERE session_id = @@spid
Zwrócony
internal_objects_alloc_page_co
2144456
więc zakładam, że to wszystko jest po prostu zapisywane na LOB
stronach tempdb
bez sprawdzania długości. Wzrost liczby stron był związany ze SET @y = REPLICATE(@y,92681);
stwierdzeniem. 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 ma 8 KB, wychodzi to na 16,36 GB, co jest oczywiście 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 dołączenia fragmentu 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
Przetestowałem również zachowanie z łączeniem nvarchar(max) + nvarchar(max)
i nvarchar(max) + varchar(max)
. Oba pozwalają na przekroczenie limitu 2 GB. Próba zapisania wyników w tabeli kończy się jednak niepowodzeniem i Attempting to grow LOB beyond maximum allowed size of 2147483647 bytes.
ponownie pojawia się komunikat o błędzie . Skrypt do tego znajduje się poniżej (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)
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))
daje4294967294
mi, ale bieganie zajmuje dużo czasu - nawet poSELECT
powrocie, więc nie jestem pewien, na co ten dodatkowy czas spędza.