Ich verstehe, dass es ein Maximum von 4000 gibt NVARCHAR(MAX)
Dein Verständnis ist falsch. nvarchar(max)
kann bis zu (und manchmal auch darüber hinaus) 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. dh Sie geben entweder n
oder das Literal an max
.
Wenn Sie sich für die Angabe eines bestimmten Objekts entscheiden, n
muss dieses zwischen 1 und 4.000 liegen. Bei Verwendung wird max
es jedoch als Datentyp für große Objekte definiert (dessen Ersatz ntext
veraltet ist).
Tatsächlich scheint es in SQL Server 2008 so zu sein, dass für eine Variable das 2-GB-Limit auf unbestimmte Zeit überschritten werden kann, sofern genügend Speicherplatz in tempdb
( hier gezeigt ) vorhanden ist.
In Bezug auf die anderen Teile 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, so dass das Ergebnis istnvarchar(4,000)
[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 wie folgt eingegeben varchar(max)
.
varchar(max)
+ nvarchar(n)
wird nicht abgeschnitten (für <2 GB) und das Ergebnis wird wie folgt eingegeben nvarchar(max)
.
nvarchar(max)
+ varchar(n)
konvertiert zuerst die varchar(n)
Eingabe in nvarchar(n)
und führt dann die Verkettung durch. Wenn die Länge der varchar(n)
Zeichenfolge größer als 4.000 Zeichen ist, erfolgt die nvarchar(4000)
Umwandlung und es kommt zu einem Abschneiden .
Datentypen von String-Literalen
Wenn Sie die Verwendung N
Präfix und die Zeichenfolge <= 4.000 Zeichen lange wird es als eingegeben werden , nvarchar(n)
wo n
die Länge der Saite. So N'Foo'
wird wie nvarchar(3)
zum Beispiel behandelt . Wenn die Zeichenfolge länger als 4.000 Zeichen ist, wird sie als behandeltnvarchar(max)
Wenn Sie nicht über die Verwendung N
Präfix und die Zeichenfolge <= 8.000 Zeichen lange wird es als eingegeben werden , varchar(n)
wo n
die Länge der Saite. Wenn länger alsvarchar(max)
Wenn für beide oben genannten Punkte die Länge der Zeichenfolge Null n
ist, wird sie auf 1 gesetzt.
Neuere Syntaxelemente.
1. Die 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);`
Kehrt zurück
-------------------- --------------------
8000 10000
Beachten Sie, dass @A
eine Kürzung aufgetreten ist.
So lösen Sie das aufgetretene Problem.
Sie werden entweder abgeschnitten, weil Sie zwei Nicht- max
Datentypen miteinander verketten oder weil Sie eine varchar(4001 - 8000)
Zeichenfolge mit einer nvarchar
typisierten Zeichenfolge (gerade nvarchar(max)
) verknüpfen .
Um das zweite Problem zu vermeiden, stellen Sie einfach sicher, dass alle Zeichenfolgenliterale (oder zumindest diejenigen mit Längen im Bereich von 4001 bis 8000) vorangestellt sind N
.
Um das erste Problem zu vermeiden, ändern Sie die Zuordnung von
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
Zu
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
so dass ein NVARCHAR(MAX)
von Anfang an an der Verkettung beteiligt ist (als Ergebnis jeder Verkettung wird sich NVARCHAR(MAX)
dies auch ausbreiten)
Vermeiden von Kürzungen beim Anzeigen
Stellen Sie sicher, dass der Modus "Ergebnisse in Raster" ausgewählt ist, den Sie verwenden können
select @SQL as [processing-instruction(x)] FOR XML PATH
Mit den SSMS-Optionen können Sie eine unbegrenzte Länge für XML
Ergebnisse festlegen . Das processing-instruction
Bit vermeidet Probleme mit Zeichen wie <
das Anzeigen als <
.