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, n
musi to być od 1 do 4000, ale użycie max
definiuje go jako typ danych dużego obiektu (zamiennik ntext
jest 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. nvarchar
ma 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 N
prefiksu, a ciąg ma <= 4000 znaków, zostanie on wpisany jako nvarchar(n)
gdzie n
jest 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 N
prefiksu, a ciąg ma <= 8000 znaków, zostanie on wpisany jako varchar(n)
gdzie n
jest 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 n
jest 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 @A
napotkano obcięcie.
Jak rozwiązać napotkany problem.
Otrzymujesz obcięcie, ponieważ łączysz ze sobą dwa max
typy niebędące typami danych lub ponieważ łączysz varchar(4001 - 8000)
łańcuch z nvarchar
wpisanym 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ść XML
wyników. Ten processing-instruction
bit pozwala uniknąć problemów ze znakami, takimi jak <
wyświetlanie jako <
.