All, I have a large (unavoidable) dynamic SQL query. Due to the number of fields in the selection criteria the string containing the dynamic SQL is growing over 4000 chars. Now, I understand that there is a 4000 max set for NVARCHAR(MAX), but looking at the executed SQL in Server Profiler for the statement
DELARE @SQL NVARCHAR(MAX);
SET @SQL = 'SomeMassiveString > 4000 chars...';
EXEC(@SQL);
GO
Seems to work(!?), for another query that is also large it throws an error which is associated with this 4000 limit(!?), it basically trims all of the SQL after this 4000 limit and leaves me with a syntax error. Despite this in the profiler, it is showing this dynamic SQL query in full(!?).
What exactly is happening here and should I just be converting this @SQL variable to VARCHAR and get on with it?
Thanks for your time.
Ps. It would also be nice to be able to print out more than 4000 chars to look at these big queries. The following are limited to 4000
SELECT CONVERT(XML, @SQL);
PRINT(@SQL);
is there any other cool way?
Your understanding is wrong.
nvarchar(max)can store up to (and beyond sometimes) 2GB of data (1 billion double byte characters).From nchar and nvarchar in Books online the grammar is
The
|character means these are alternatives. i.e. you specify eithernor the literalmax.If you choose to specify a specific
nthen this must be between 1 and 4,000 but usingmaxdefines it as a large object datatype (replacement forntextwhich is deprecated).In fact in SQL Server 2008 it seems that for a variable the 2GB limit can be exceeded indefinitely subject to sufficient space in
tempdb(Shown here)Regarding the other parts of your question
Truncation when concatenating depends on datatype.
varchar(n) + varchar(n)will truncate at 8,000 characters.nvarchar(n) + nvarchar(n)will truncate at 4,000 characters.varchar(n) + nvarchar(n)will truncate at 4,000 characters.nvarcharhas higher precedence so the result isnvarchar(4,000)[n]varchar(max)+[n]varchar(max)won’t truncate (for < 2GB).varchar(max)+varchar(n)won’t truncate (for < 2GB) and the result will be typed asvarchar(max).varchar(max)+nvarchar(n)won’t truncate (for < 2GB) and the result will be typed asnvarchar(max).nvarchar(max)+varchar(n)will first convert thevarchar(n)input tonvarchar(n)and then do the concatenation. If the length of thevarchar(n)string is greater than 4,000 characters the cast will be tonvarchar(4000)and truncation will occur.Datatypes of string literals
If you use the
Nprefix and the string is <= 4,000 characters long it will be typed asnvarchar(n)wherenis the length of the string. SoN'Foo'will be treated asnvarchar(3)for example. If the string is longer than 4,000 characters it will be treated asnvarchar(max)If you don’t use the
Nprefix and the string is <= 8,000 characters long it will be typed asvarchar(n)wherenis the length of the string. If longer asvarchar(max)For both of the above if the length of the string is zero then
nis set to 1.Newer syntax elements.
1. The
CONCATfunction doesn’t help hereThe above returns 8000 for both methods of concatenation.
2. Be careful with
+=Returns
Note that
@Aencountered truncation.How to resolve the problem you are experiencing.
You are getting truncation either because you are concatenating two non
maxdatatypes together or because you are concatenating avarchar(4001 - 8000)string to annvarchartyped string (evennvarchar(max)).To avoid the second issue simply make sure that all string literals (or at least those with lengths in the 4001 – 8000 range) are prefaced with
N.To avoid the first issue change the assignment from
To
so that an
NVARCHAR(MAX)is involved in the concatenation from the beginning (as the result of each concatenation will also beNVARCHAR(MAX)this will propagate)Avoiding truncation when viewing
Make sure you have "results to grid" mode selected then you can use
The SSMS options allow you to set unlimited length for
XMLresults. Theprocessing-instructionbit avoids issues with characters such as<showing up as<.