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, ncelui-ci doit être compris entre 1 et 4 000, mais l'utilisation le maxdéfinit comme un type de données objet volumineux (dont le remplacement ntextest 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. nvarchara 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 Npréfixe et que la chaîne est <= 4 000 caractères, il sera tapé comme nvarchar(n)où nest 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 Npréfixe et que la chaîne est <= 8 000 caractères, elle sera tapée comme varchar(n)où nest 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 nest définie sur 1.
Nouveaux éléments de syntaxe.
1. La CONCATfonction 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 @Atroncature rencontrée.
Comment résoudre le problème que vous rencontrez.
Vous obtenez une troncature soit parce que vous concaténez deux maxtypes de données non ensemble, soit parce que vous concaténez une varchar(4001 - 8000)chaîne en une nvarcharchaî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 XMLrésultats. Le processing-instructionbit évite les problèmes avec les caractères tels que <apparaître comme <.