Ich verstehe, dass für NVARCHAR(MAX)
ein Maximum von 4000 festgelegt ist
Ihr Verständnis ist falsch. nvarchar(max)
kann bis zu (und manchmal mehr) 2 GB Daten (1 Milliarde Doppelbyte-Zeichen) speichern.
Von nchar und nvarchar in Books online ist die Grammatik
nvarchar [ ( n | max ) ]
Der |
Charakter bedeutet, dass dies Alternativen sind. d.h. Sie geben entweder an n
oder das wörtliche max
.
Wenn Sie sich dafür entscheiden, einen bestimmten n
anzugeben dann muss dieser zwischen 1 und 4.000 liegen, aber mit max
definiert es als großen Objektdatentyp (Ersatz für ntext
die veraltet ist).
Tatsächlich scheint es in SQL Server 2008 für eine Variable Die 2-GB-Grenze kann unbegrenzt überschritten werden, sofern in tempdb
ausreichend Speicherplatz vorhanden ist (hier gezeigt)
Zu den anderen Teilen Ihrer Frage
Das Abschneiden beim Verketten hängt vom Datentyp ab.
varchar(n) + varchar(n)
wird bei 8.000 Zeichen abgeschnitten.nvarchar(n) + nvarchar(n)
wird bei 4.000 Zeichen abgeschnitten.varchar(n) + nvarchar(n)
wird bei 4.000 Zeichen abgeschnitten.nvarchar
hat eine höhere Priorität, sodass das Ergebnisnvarchar(4,000)
ist[n]varchar(max)
+[n]varchar(max)
wird nicht abgeschnitten (für <2 GB).varchar(max)
+varchar(n)
wird nicht abgeschnitten (für <2 GB) und das Ergebnis wird alsvarchar(max)
eingegeben .varchar(max)
+nvarchar(n)
wird nicht abgeschnitten (für <2 GB) und das Ergebnis wird alsnvarchar(max)
eingegeben .nvarchar(max)
+varchar(n)
konvertiert zuerst denvarchar(n)
Eingabe innvarchar(n)
und dann die Verkettung durchführen. Wenn die Länge vonvarchar(n)
string länger als 4.000 Zeichen ist, erfolgt die Umwandlung innvarchar(4000)
und es kommt zu einer Kürzung .
Datentypen von String-Literalen
Wenn Sie das N
verwenden Präfix und die Zeichenfolge <=4.000 Zeichen lang ist, wird sie als nvarchar(n)
eingegeben wobei n
ist die Länge der Zeichenfolge. Also N'Foo'
wird als nvarchar(3)
behandelt zum Beispiel. Wenn die Zeichenfolge länger als 4.000 Zeichen ist, wird sie als nvarchar(max)
behandelt
Wenn Sie das N
nicht verwenden Präfix und die Zeichenfolge <=8.000 Zeichen lang ist, wird sie als varchar(n)
eingegeben wobei n
ist die Länge der Zeichenfolge. Wenn länger als varchar(max)
Wenn die Länge der Zeichenfolge Null ist, dann n
auf 1 gesetzt.
Neuere Syntaxelemente.
1. Der CONCAT
Funktion hilft hier nicht
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Das Obige gibt 8000 für beide Verkettungsmethoden zurück.
2. Seien Sie vorsichtig mit +=
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);`
Rückgabe
-------------------- --------------------
8000 10000
Beachten Sie, dass @A
Trunkierung aufgetreten.
So lösen Sie das aufgetretene Problem.
Sie werden entweder abgeschnitten, weil Sie zwei Nicht-max
verketten Datentypen zusammen oder weil Sie ein varchar(4001 - 8000)
verketten string zu einem nvarchar
eingegebene Zeichenfolge (auch nvarchar(max)
).
Um das zweite Problem zu vermeiden, stellen Sie einfach sicher, dass allen Zeichenfolgenliteralen (oder zumindest denen mit Längen im Bereich von 4001 bis 8000) ein vorangestelltes N
vorangestellt wird .
Um das erste Problem zu vermeiden, ändern Sie die Zuweisung von
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
An
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
so dass ein NVARCHAR(MAX)
ist von Anfang an an der Verkettung beteiligt (da das Ergebnis jeder Verkettung auch NVARCHAR(MAX)
ist dies wird sich ausbreiten)
Vermeiden von Abschneiden beim Anzeigen
Stellen Sie sicher, dass Sie den Modus "Ergebnisse ins Raster" ausgewählt haben, dann können Sie ihn verwenden
select @SQL as [processing-instruction(x)] FOR XML PATH
Mit den SSMS-Optionen können Sie eine unbegrenzte Länge für XML
festlegen Ergebnisse. Die processing-instruction
bit vermeidet Probleme mit Zeichen wie <
wird als <
angezeigt .