SQL Server Management Studio and very large strings

Hi folks

When you want to work with very large strings within SQL Server Management Studio you may suddenly discover some inconvenient limitations.

They described in details: http://stackoverflow.com/questions/4833549/nvarcharmax-still-being-truncated and http://stackoverflow.com/questions/12639948/sql-nvarchar-and-varchar-limits

See the most important parts from these articles below.

Many of those limitations include length 4000 so we’ll heavily use it in our examples
Consider the following sql script

DECLARE @str nvarchar(max)
SET @str = REPLICATE('A', 4000) + REPLICATE('B', 4000) + REPLICATE('C', 4000)
PRINT LEN(@str)

You’d expect to get 12000 as a result, but the actual result is 8000 instead. The reason for that is in the limitations mentioned on the links above. Actually it has a simple workaround.

DECLARE @str nvarchar(max)
SET @str = ''
SET @str = @str + REPLICATE('A', 4000) + REPLICATE('B', 4000) + REPLICATE('C', 4000)
PRINT LEN(@str)

This returns 12000 as expected.

The secret here is to put nvarchar(max) as a first argument in concatenation.

Alternatively, we can use

DECLARE @str nvarchar(max)
SET @str = CONVERT(nvarchar(max), '') + REPLICATE('A', 4000) + REPLICATE('B', 4000) + REPLICATE('C', 4000)
PRINT LEN(@str)

This also gives 12000 characters

I would recommend to use this trick whenever you construct long strings in sql such as dynamic sql queries. I personally had some data truncated and that’s how I discovered this issue.

Another problem is how to get a long string value from the database

Consider

DECLARE @str nvarchar(max)
SET @str = CONVERT(nvarchar(max), '') + REPLICATE('A', 4000) + REPLICATE('B', 4000) + REPLICATE('D', 4000) + REPLICATE('E', 4000) + REPLICATE('F', 4000) + REPLICATE('G', 4000) + REPLICATE('H', 4000) + REPLICATE('I', 4000) + REPLICATE('J', 4000) + REPLICATE('K', 4000) + REPLICATE('L', 4000) + REPLICATE('M', 4000)

PRINT LEN(@str)
SELECT @str

We can see that LEN returned 48000 as expected.

However, if we copy the value from the result table and insert it into any text editor, we’ll get only 43679 characters ending with L so we’ve lost 4321 characters truncated including 321 L’s and 4000 M’s.

Now the question is how to get the whole string

And the answer is tricky

SELECT @str AS [processing-instruction(blah)] FOR XML PATH

This would convert your string to xml and when you click on it you can copy it fully.

This processing-instruction trick allows to get the string without any xml escaping such as &, <, >, etc.
Obviously blah part can be replaced with anything.

This solution would work in 99.9% of cases. The only problem if your string contains ?> part, as this easily breaks the parser.

The easiest way to break it is

SELECT '?><' AS [processing-instruction(blah)] FOR XML PATH

Try it and see what happens 😉

So in case when your string contains ?> you have to use escaped form

SELECT @str FOR XML PATH

and then unescape it manually after you copied the text.

Stay tuned

Advertisements

About mnaoumov

Senior .NET Developer in Readify
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s