Rozumiem, że istnieje maksymalny zestaw 4000 dla NVARCHAR(MAX)
Twoje zrozumienie jest błędne. nvarchar(max) może przechowywać do (a czasami więcej) 2 GB danych (1 miliard znaków dwubajtowych).
Z nchar i nvarchar w Książkach online gramatyka to
nvarchar [ ( n | max ) ]
| znak oznacza, że są to alternatywy. tzn. określasz albo n lub dosłowny max .
Jeśli zdecydujesz się określić konkretny n to musi być od 1 do 4000, ale przy użyciu max definiuje go jako typ danych dużego obiektu (zamiennik dla ntext który jest przestarzały).
W rzeczywistości w SQL Server 2008 wydaje się, że dla zmiennej limit 2GB może zostać przekroczony w nieskończoność pod warunkiem wystarczającej ilości miejsca w tempdb (pokazane tutaj)
Odnośnie innych części Twojego pytania
Obcięcie podczas łączenia zależy od typu danych.
varchar(n) + varchar(n)zostanie skrócony do 8000 znaków.nvarchar(n) + nvarchar(n)zostanie skrócony do 4000 znaków.varchar(n) + nvarchar(n)zostanie skrócony do 4000 znaków.nvarcharma wyższy priorytet, więc wynikiem jestnvarchar(4,000)[n]varchar(max)+[n]varchar(max)nie zostanie skrócony (za <2 GB).varchar(max)+varchar(n)nie zostanie obcięty (dla <2 GB), a wynik zostanie wpisany jakovarchar(max).varchar(max)+nvarchar(n)nie zostanie obcięty (dla <2 GB), a wynik zostanie wpisany jakonvarchar(max).nvarchar(max)+varchar(n)najpierw skonwertujevarchar(n)wejście donvarchar(n)a następnie wykonaj konkatenację. Jeśli długośćvarchar(n)ciąg znaków jest większy niż 4000 znaków, które rzutowane będą nanvarchar(4000)i nastąpi obcięcie .
Typy danych literałów łańcuchowych
Jeśli używasz N prefiks, a ciąg ma długość <=4000 znaków, zostanie wpisany jako nvarchar(n) gdzie n to długość ciągu. Więc N'Foo' będzie traktowane jako nvarchar(3) na przykład. Jeśli ciąg jest dłuższy niż 4000 znaków, zostanie potraktowany jako nvarchar(max)
Jeśli nie używasz N prefiks, a ciąg ma długość <=8000 znaków, zostanie wpisany jako varchar(n) gdzie n to długość ciągu. Jeśli jest dłuższy niż varchar(max)
Dla obu powyższych, jeśli długość ciągu wynosi zero, to n jest ustawiony na 1.
Nowsze elementy składni.
1. CONCAT funkcja tu nie pomaga
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Powyższe zwraca 8000 dla obu metod łączenia.
2. Uważaj na +=
DECLARE @A VARCHAR(MAX) = '';
SET @A+= REPLICATE('A',5000) + REPLICATE('A',5000)
DECLARE @B VARCHAR(MAX) = '';
SET @B = @B + REPLICATE('A',5000) + REPLICATE('A',5000)
SELECT DATALENGTH(@A),
DATALENGTH(@B);`
Zwroty
-------------------- --------------------
8000 10000
Zauważ, że @A napotkał obcięcie.
Jak rozwiązać napotkany problem.
Dostajesz obcięcie, ponieważ łączysz dwa inne niż max typy danych razem lub ponieważ łączysz varchar(4001 - 8000) ciąg do nvarchar wpisany ciąg (nawet nvarchar(max) ).
Aby uniknąć drugiego problemu, po prostu upewnij się, że wszystkie literały łańcuchowe (lub przynajmniej te o długości z zakresu 4001 - 8000) są poprzedzone N .
Aby uniknąć pierwszego problemu, zmień przypisanie z
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
Do
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
aby NVARCHAR(MAX) bierze udział w konkatenacji od samego początku (ponieważ wynikiem każdej konkatenacji będzie również NVARCHAR(MAX) to się rozprzestrzeni)
Unikanie obcinania podczas przeglądania
Upewnij się, że masz wybrany tryb „wyniki do siatki”, a następnie możesz użyć
select @SQL as [processing-instruction(x)] FOR XML PATH
Opcje SSMS pozwalają ustawić nieograniczoną długość dla XML wyniki. processing-instruction bit pozwala uniknąć problemów ze znakami takimi jak < wyświetlane jako < .