Rozumiem, że jest ustawiony maksymalny 4000 NVARCHAR(MAX)
Twoje rozumienie jest błędne. nvarchar(max)może przechowywać do (a czasami więcej) 2 GB danych (1 miliard znaków dwubajtowych).
Od nchar i nvarchar w Book online gramatyka jest
nvarchar [ ( n | max ) ]
Te |środki te mają charakter alternatywy. tzn. określasz albo n albo literał max.
Jeśli zdecydujesz się określić konkretny, nmusi to być od 1 do 4000, ale użycie maxdefiniuje go jako typ danych dużego obiektu (zamiennik ntextjest przestarzały).
W rzeczywistości w SQL Server 2008 wydaje się, że dla zmiennej limit 2 GB może zostać przekroczony w nieskończoność, z zastrzeżeniem wystarczającej ilości miejsca w tempdb( pokazane tutaj )
Odnośnie innych części twojego pytania
Obcinanie przy konkatenacji zależy od typu danych.
varchar(n) + varchar(n) zostanie obcięty do 8 000 znaków.
nvarchar(n) + nvarchar(n) zostanie obcięty do 4000 znaków.
varchar(n) + nvarchar(n)zostanie obcięty do 4000 znaków. nvarcharma wyższy priorytet, więc wynik jestnvarchar(4,000)
[n]varchar(max)+ [n]varchar(max)nie zostanie obcięty (dla <2 GB).
varchar(max)+ varchar(n)nie zostanie obcięty (dla <2 GB), a wynik zostanie wpisany jako varchar(max).
varchar(max)+ nvarchar(n)nie zostanie obcięty (dla <2 GB), a wynik zostanie wpisany jako nvarchar(max).
nvarchar(max)+ varchar(n)najpierw przekonwertuje dane varchar(n)wejściowe, nvarchar(n)a następnie dokona konkatenacji. Jeśli długość varchar(n)ciągu jest większa niż 4000 znaków, rzutowanie zostanie skierowane na nvarchar(4000)i nastąpi obcięcie .
Typy danych literałów łańcuchowych
Jeśli użyjesz Nprefiksu, a ciąg ma <= 4000 znaków, zostanie on wpisany jako nvarchar(n)gdzie njest długością ciągu. Tak N'Foo'będzie traktowane jak nvarchar(3)np. Jeśli ciąg jest dłuższy niż 4000 znaków, zostanie potraktowany jakonvarchar(max)
Jeśli nie użyjesz Nprefiksu, a ciąg ma <= 8000 znaków, zostanie on wpisany jako varchar(n)gdzie njest długością łańcucha. Jeśli dłużej jakvarchar(max)
Dla obu powyższych, jeśli długość łańcucha wynosi zero, to njest ustawiana na 1.
Nowsze elementy składni.
1.CONCAT funkcja nie pomaga tutaj
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Powyższe zwraca 8000 dla obu metod konkatenacji.
2. Uważaj z+=
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 @Anapotkano obcięcie.
Jak rozwiązać napotkany problem.
Otrzymujesz obcięcie, ponieważ łączysz ze sobą dwa maxtypy niebędące typami danych lub ponieważ łączysz varchar(4001 - 8000)łańcuch z nvarcharwpisanym ciągiem (parzystym nvarchar(max)).
Aby uniknąć drugiego problemu, po prostu upewnij się, że wszystkie literały łańcuchowe (lub przynajmniej te o długościach z zakresu 4001 - 8000) są poprzedzone N.
Aby uniknąć pierwszego problemu, zmień przydział z
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
Do
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
tak, aby an NVARCHAR(MAX)był zaangażowany w konkatenację od początku (w wyniku każdego konkatenacji będzie to również się NVARCHAR(MAX)propagować)
Unikanie obcinania podczas przeglądania
Upewnij się, że masz wybrany tryb „wyniki do siatki”, a następnie możesz go użyć
select @SQL as [processing-instruction(x)] FOR XML PATH
Opcje SSMS pozwalają ustawić nieograniczoną długość XMLwyników. Ten processing-instructionbit pozwala uniknąć problemów ze znakami, takimi jak <wyświetlanie jako <.