Je comprends qu'il existe un ensemble de 4000 max pour
NVARCHAR(MAX)
Votre compréhension est erronée. nvarchar(max)
peut stocker jusqu'à (et parfois au-delà) 2 Go de données (1 milliard de caractères à double octet).
De nchar et nvarchar dans Livres en ligne, la grammaire est
nvarchar [ ( n | max ) ]
Le |
caractère signifie qu'il s'agit d'alternatives. c'est-à-dire que vous spécifiez soit n
ou le littéral max
.
Si vous choisissez de spécifier un n
spécifique alors cela doit être compris entre 1 et 4 000 mais en utilisant max
le définit comme un type de données d'objet volumineux (remplacement de ntext
qui est obsolète).
En fait dans SQL Server 2008 il semble que pour une variable la limite de 2 Go peut être dépassée indéfiniment sous réserve d'un espace suffisant dans tempdb
(Montré ici)
Concernant les autres parties de votre question
La troncation lors de la concaténation dépend du type de données.
varchar(n) + varchar(n)
sera tronqué à 8 000 caractères.nvarchar(n) + nvarchar(n)
sera tronqué à 4 000 caractères.varchar(n) + nvarchar(n)
sera tronqué à 4 000 caractères.nvarchar
a une priorité plus élevée donc le résultat estnvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
ne sera pas tronqué (pour <2 Go).varchar(max)
+varchar(n)
ne sera pas tronqué (pour <2 Go) et le résultat sera saisi sous la formevarchar(max)
.varchar(max)
+nvarchar(n)
ne sera pas tronqué (pour <2 Go) et le résultat sera saisi sous la formenvarchar(max)
.nvarchar(max)
+varchar(n)
convertira d'abord levarchar(n)
entrée dansnvarchar(n)
puis faire la concaténation. Si la longueur duvarchar(n)
la chaîne est supérieure à 4 000 caractères, le cast sera ennvarchar(4000)
et la troncation se produira .
Types de données des littéraux de chaîne
Si vous utilisez le N
préfixe et la chaîne fait <=4 000 caractères, elle sera saisie sous la forme nvarchar(n)
où n
est la longueur de la chaîne. Alors N'Foo'
sera traité comme nvarchar(3)
par exemple. Si la chaîne contient plus de 4 000 caractères, elle sera traitée comme nvarchar(max)
Si vous n'utilisez pas le N
préfixe et la chaîne fait <=8 000 caractères, elle sera saisie sous la forme varchar(n)
où n
est la longueur de la chaîne. Si plus long que varchar(max)
Pour les deux ci-dessus, si la longueur de la chaîne est nulle, alors n
est défini sur 1.
Éléments de syntaxe plus récents.
1. Le CONCAT
la fonction n'aide pas ici
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Ce qui précède renvoie 8000 pour les deux méthodes de concaténation.
2. Soyez prudent avec +=
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);`
Retours
-------------------- --------------------
8000 10000
Notez que @A
troncature rencontrée.
Comment résoudre le problème que vous rencontrez.
Vous obtenez une troncation soit parce que vous concaténez deux non max
types de données ensemble ou parce que vous concaténez un varchar(4001 - 8000)
chaîne à un nvarchar
chaîne tapée (même nvarchar(max)
).
Pour éviter le deuxième problème, assurez-vous simplement que tous les littéraux de chaîne (ou au moins ceux dont la longueur est comprise entre 4001 et 8000) sont précédés de N
.
Pour éviter le premier problème, modifiez l'affectation de
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
À
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
de sorte qu'un NVARCHAR(MAX)
est impliqué dans la concaténation depuis le début (car le résultat de chaque concaténation sera également NVARCHAR(MAX)
cela se propagera)
Éviter la troncation lors de la visualisation
Assurez-vous que le mode "résultats sur la grille" est sélectionné, puis vous pouvez utiliser
select @SQL as [processing-instruction(x)] FOR XML PATH
Les options SSMS vous permettent de définir une longueur illimitée pour XML
résultats. L'processing-instruction
bit évite les problèmes avec des caractères tels que <
apparaissant comme <
.