Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

SQL NVARCHAR- und VARCHAR-Limits

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.

  1. varchar(n) + varchar(n) wird bei 8.000 Zeichen abgeschnitten.
  2. nvarchar(n) + nvarchar(n) wird bei 4.000 Zeichen abgeschnitten.
  3. varchar(n) + nvarchar(n) wird bei 4.000 Zeichen abgeschnitten. nvarchar hat eine höhere Priorität, sodass das Ergebnis nvarchar(4,000) ist
  4. [n]varchar(max) + [n]varchar(max) wird nicht abgeschnitten (für <2 GB).
  5. varchar(max) + varchar(n) wird nicht abgeschnitten (für <2 GB) und das Ergebnis wird als varchar(max) eingegeben .
  6. varchar(max) + nvarchar(n) wird nicht abgeschnitten (für <2 GB) und das Ergebnis wird als nvarchar(max) eingegeben .
  7. nvarchar(max) + varchar(n) konvertiert zuerst den varchar(n) Eingabe in nvarchar(n) und dann die Verkettung durchführen. Wenn die Länge von varchar(n) string länger als 4.000 Zeichen ist, erfolgt die Umwandlung in nvarchar(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 &lt; wird als &lt; angezeigt .