Je comprends qu'il existe un ensemble de 4000 max pour NVARCHAR(MAX)
Votre compréhension est fausse. nvarchar(max)
peut stocker jusqu'à (et parfois au-delà) 2 Go de données (1 milliard de caractères à deux octets).
De nchar et nvarchar dans les livres en ligne, la grammaire est
nvarchar [ ( n | max ) ]
Le |
caractère signifie que ce sont des alternatives. c'est-à-dire que vous spécifiez l' un n
ou l' autre ou le littéral max
.
Si vous choisissez de spécifier un objet spécifique, n
celui-ci doit être compris entre 1 et 4 000, mais l'utilisation le max
définit comme un type de données objet volumineux (dont le remplacement ntext
est déconseillé).
En fait, dans SQL Server 2008, il semble que pour une variable, la limite de 2 Go puisse ê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 troncature lors de la concaténation dépend du type de données.
varchar(n) + varchar(n)
tronquera à 8 000 caractères.
nvarchar(n) + nvarchar(n)
tronquera à 4 000 caractères.
varchar(n) + nvarchar(n)
tronquera à 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 tronquera pas (pour <2 Go).
varchar(max)
+ varchar(n)
ne tronquera pas (pour <2 Go) et le résultat sera tapé comme varchar(max)
.
varchar(max)
+ nvarchar(n)
ne tronquera pas (pour <2 Go) et le résultat sera tapé comme nvarchar(max)
.
nvarchar(max)
+ varchar(n)
convertira d'abord l' varchar(n)
entrée en nvarchar(n)
puis effectuera la concaténation. Si la longueur de la varchar(n)
chaîne est supérieure à 4 000 caractères, la conversion sera effectuée nvarchar(4000)
et une troncature se produira .
Types de données de littéraux de chaîne
Si vous utilisez le N
préfixe et que la chaîne est <= 4 000 caractères, il sera tapé comme nvarchar(n)
où n
est la longueur de la chaîne. Ainsi N'Foo'
sera traité comme nvarchar(3)
par exemple. Si la chaîne contient plus de 4000 caractères, elle sera traitée commenvarchar(max)
Si vous n'utilisez pas le N
préfixe et que la chaîne est <= 8 000 caractères, elle sera tapée comme varchar(n)
où n
est la longueur de la chaîne. Si plus long quevarchar(max)
Pour les deux éléments ci-dessus, si la longueur de la chaîne est égale à zéro, elle n
est définie sur 1.
Nouveaux éléments de syntaxe.
1. La CONCAT
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);`
Retour
-------------------- --------------------
8000 10000
Notez que la @A
troncature rencontrée.
Comment résoudre le problème que vous rencontrez.
Vous obtenez une troncature soit parce que vous concaténez deux max
types de données non ensemble, soit parce que vous concaténez une varchar(4001 - 8000)
chaîne en une nvarchar
chaîne typée (paire 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'attribution 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 (comme le résultat de chaque concaténation sera également NVARCHAR(MAX)
cela se propagera)
Éviter la troncature lors de la visualisation
Assurez-vous que vous avez sélectionné le mode «résultats sur grille», puis utilisez
select @SQL as [processing-instruction(x)] FOR XML PATH
Les options SSMS vous permettent de définir une longueur illimitée pour les XML
résultats. Le processing-instruction
bit évite les problèmes avec les caractères tels que <
apparaître comme <
.