Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Limites SQL NVARCHAR et VARCHAR

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.

  1. varchar(n) + varchar(n) sera tronqué à 8 000 caractères.
  2. nvarchar(n) + nvarchar(n) sera tronqué à 4 000 caractères.
  3. varchar(n) + nvarchar(n) sera tronqué à 4 000 caractères. nvarchar a une priorité plus élevée donc le résultat est nvarchar(4,000)
  4. [n]varchar(max) + [n]varchar(max) ne sera pas tronqué (pour <2 Go).
  5. varchar(max) + varchar(n) ne sera pas tronqué (pour <2 Go) et le résultat sera saisi sous la forme varchar(max) .
  6. varchar(max) + nvarchar(n) ne sera pas tronqué (pour <2 Go) et le résultat sera saisi sous la forme nvarchar(max) .
  7. nvarchar(max) + varchar(n) convertira d'abord le varchar(n) entrée dans nvarchar(n) puis faire la concaténation. Si la longueur du varchar(n) la chaîne est supérieure à 4 000 caractères, le cast sera en nvarchar(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)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)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 &lt; apparaissant comme &lt; .