Tous, j'ai une grande requête SQL dynamique (inévitable). En raison du nombre de champs dans les critères de sélection, la chaîne contenant le SQL dynamique augmente de plus de 4000 caractères. Maintenant, je comprends qu'il existe un ensemble de 4000 max NVARCHAR(MAX)
, mais en regardant le SQL exécuté dans Server Profiler pour l'instruction
DELARE @SQL NVARCHAR(MAX);
SET @SQL = 'SomeMassiveString > 4000 chars...';
EXEC(@SQL);
GO
Cela semble fonctionner (!?), pour une autre requête qui est également grande, cela génère une erreur associée à cette limite de 4000 (!?), cela supprime fondamentalement tout le SQL après cette limite de 4000 et me laisse avec une erreur de syntaxe. Malgré cela dans le profileur, il affiche cette requête SQL dynamique dans son intégralité (!?).
Que se passe-t-il exactement ici et devrais-je simplement convertir cette variable @SQL en VARCHAR et continuer?
Merci pour votre temps.
Ps. Ce serait également bien de pouvoir imprimer plus de 4000 caractères pour regarder ces grosses requêtes. Les éléments suivants sont limités à 4000
SELECT CONVERT(XML, @SQL);
PRINT(@SQL);
y a-t-il une autre façon cool?
Réponses:
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
Le
|
caractère signifie que ce sont des alternatives. c'est-à-dire que vous spécifiez l' unn
ou l' autre ou le littéralmax
.Si vous choisissez de spécifier un objet spécifique,
n
celui-ci doit être compris entre 1 et 4 000, mais l'utilisation lemax
définit comme un type de données objet volumineux (dont le remplacementntext
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é commevarchar(max)
.varchar(max)
+nvarchar(n)
ne tronquera pas (pour <2 Go) et le résultat sera tapé commenvarchar(max)
.nvarchar(max)
+varchar(n)
convertira d'abord l'varchar(n)
entrée ennvarchar(n)
puis effectuera la concaténation. Si la longueur de lavarchar(n)
chaîne est supérieure à 4 000 caractères, la conversion sera effectuéenvarchar(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é commenvarchar(n)
oùn
est la longueur de la chaîne. AinsiN'Foo'
sera traité commenvarchar(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 commevarchar(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 iciCe qui précède renvoie 8000 pour les deux méthodes de concaténation.
2. Soyez prudent avec
+=
Retour
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 unevarchar(4001 - 8000)
chaîne en unenvarchar
chaîne typée (pairenvarchar(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
À
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 égalementNVARCHAR(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
Les options SSMS vous permettent de définir une longueur illimitée pour les
XML
résultats. Leprocessing-instruction
bit évite les problèmes avec les caractères tels que<
apparaître comme<
.la source
nvarchar(4000)
cours de route. Si un littéral de chaîne contient moins de 4 000 caractères, il est traité commenvarchar(x)
. La concaténation avec une autrenvarchar(x)
valeur tronquera plutôt que l'upcast versnvarchar(max)
DECLARE @SQL NVARCHAR(MAX) = ''; SET @SQL = @SQL +
pour qu’unNVARCHAR(MAX)
soit impliqué dans la concaténation.N
préfixe qui sera traité commenvarchar(max)
sans lui, il sera traité commevarchar(n)
alors implicitement convertinvarchar(4000)
lorsque vous concaténez en unnvarchar
D'accord, donc si plus tard, le problème est que vous avez une requête supérieure à la taille autorisée (ce qui peut arriver si elle continue de croître), vous devrez la diviser en morceaux et exécuter les valeurs de chaîne. Donc, disons que vous avez une procédure stockée comme la suivante:
la source
Vous devez également utiliser le texte nvarchar. cela signifie que vous devez simplement avoir un "N" avant votre chaîne massive et c'est tout! plus aucune limitation
la source
nvarchar(n)
où n est la longueur de la chaîne. Donc N'Foo 'sera traité commenvarchar(3)
par exemple. Si la chaîne contient plus de 4 000 caractères, elle sera traitée commenvarchar(max)
. Si vous n'utilisez pas le préfixe N et que la chaîne est <= 8 000 caractères, elle sera tapée commevarchar(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, n est défini sur 1.La réponse acceptée m'a aidé mais j'ai trébuché en faisant la concaténation de varchars impliquant des déclarations de cas. Je sais que la question du PO n'implique pas d'énoncés de cas, mais j'ai pensé que ce serait utile de poster ici pour d'autres comme moi qui se sont retrouvés ici tout en luttant pour créer de longues instructions SQL dynamiques impliquant des instructions de cas.
Lors de l'utilisation d'instructions case avec concaténation de chaînes, les règles mentionnées dans la réponse acceptée s'appliquent à chaque section de l'instruction case indépendamment.
la source
la source