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.nvarchar
ma 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 <
.