Cast FOR XML to Varchar(max) [duplicate] - sql-server

This question already has an answer here:
For XML length limitation
(1 answer)
Closed 10 years ago.
I have a query that returns XML which I want to convert to varchar. My query returns 93,643 characters of XML. When I try to cast my xml result as varchar, I only get 43,679 characters when I copy the result set to a text editor. When I do len(xmlString), I get 93,643 characters.
I know from this post that varchar(max) can have up to 2^31 characters and 1 byte = 1 character, but it seems to be cutting off my data.
Do XML characters count as more than 1 byte? Why am I not able to select all the data from my xml result?
CAST((SELECT COLUMNS FROM TABLE FOR XML PATH('Name'), TYPE) AS VARCHAR(MAX)

This is just a limitation of the Managementstudio.
With a testquery on a bigger table I get described 43,679 characters.
The same Query deliveres 267089 characters in a application via ADO.

Not sure why you need to cast you xml data to varchar(max) but if you just want to copy all data don't cast it at all. In this case in the result window you will see one cell with a clickable value (just like a web link). Click it and all your data will be opened in a new window, then you will be able to save it like a file or just copy it. Hope it helps.

Related

SQL Server varbinary bytes not decoded consistently

We have a varbinary field storing some XML data
There is a proc which returns this field to C# calling code which decodes the byte array
Encoding.UTF8.GetString((byte[])rdr.GetValue(1))
I don't think this is decoding the byte array correctly, and I'm not sure why.
If I copy the varbinary and convert it manually, it doesn't decode correctly:
select convert(varchar(max),
0x3C4150495061796D656E7473526......)
Ä•–ÖVçG5&WVW7CàТĆVFW#àТÅ5fW#ã"ããÂõ5fW#àТÄ6Æ–VçCå
If however I simply convert the column in the proc
select convert(varchar(max), filedata), filedata from TABLE
It decodes to valid XML.
I can't unfortunately include the actual data. This behaviour is recent and not consistent.

SQL string to varbinary through XML different than nvarchar

We currently have a function in SQL which I simply do not understand.
Currently we convert a nvarchar to XML, and then select the XML value, and convert that to a varbinary.
When I try to simplify this to convert the nvarchar directly to varbinary, the output is different... Why?
--- Current situation:
Declare #inputString nvarchar(max) = '4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c'
--1: input to XML
declare #inputXML XML = convert(varchar(max), #inputString)
--2: input XML to binary
declare #inputBinray varbinary(max) = #inputXML.value('(/)[1]', 'varbinary(max)')
select #inputString -- 4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c
select #inputXML -- 4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c
select #inputBinray -- 0xE1DF79EB4E5DD5BF1FDDB71AE5E6B77B477669FDBAD36EF4D38775EF6D7CD79D9EEF6E9D6B4EB6D9DEBAF5AEF57FCE5C
--- New situation
--1: Input to binary
declare #inputString2 varbinary(max) = CAST(#inputString as varbinary(max));
select #inputString2 -- 0x3400640039003500360030003500640031006200380066003300620063006100350065006100330065003000640032006100660032003600300032003700300030003400640031003700320031003800310035003200650037003200360064006100300036003200320064003600360039006100370031006600380035006300
Using the value() function to get a XML value specified as varbinary(max) will read the data as if it was Base64 encoded. Casting a string to varbinary(max) does not, it treats it as just any string.
If you use the input string QQA= which is the letter A in UTF-16 LE encoded to Base64 you will see more clearly what is happening.
XML gives you 0x4100, the varbinary of the letter A, and direct cast on the string gives you 0x5100510041003D00 where you have two 5100 = "Q" and of course one 4100 = "A" followed by a 3D00 = "="
Might be I get something wrong, but - if I understand you correctly - I think you simply want to get a real binary from a HEX-string, which just looks like a binary. Correct?
Above I wrote "simply", but this was not simple at all a while ago.
I'm not sure at the moment, but I think it was version v2012, which enhanced CONVERT() (read about binary values and how the third parameter works) and try this:
DECLARE #hexString VARCHAR(max)='4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c';
SELECT CONVERT(varbinary(max),#hexString,2);
The result is a real binary
0x4D95605D1B8F3BCA5EA3E0D2AF26027004D17218152E726DA0622D669A71F85C
What might be the reason for your issue:
Very long ago, I think it was until v2005, the default encoding of varbinaries in XML was a HEX string. Later this was changed to base64. Might be, that you code was used in a very old environment and was upgraded to a higher version?
Today we use XML in a smiliar way to create and to read base64, which is not supported otherwise. Maybe your code did something similar with HEX strings...?
One more hint for this: The many 00 in your New Situation example show clearly, that this is a two-byte encoded NVARCHAR string. Contrary, your Current Situation shows a simple HEX string.
Your final result is just the binary pattern of your input as string:

Printing more than 8000 characters in text output [duplicate]

This question already has answers here:
How to print VARCHAR(MAX) using Print Statement?
(18 answers)
Closed 7 years ago.
There is a limit to the print output on MS SQL server (I'm using SQL Server 2014).
I've got my Maximum number of characters displayed in each column set to 8192 (the max). When I try to set a variable to a long string and print it, it gets truncated. With output set to text:
declare #text nvarchar(max)
set #text = (
select definition
from sys.sql_modules
where object_id = object_id(N'NameOfALargeStoredProcedure')
)
print #text
This will return about 4K of the characters. If I change #text to varchar (instead of nvarchar) I get around 8K characters.
The definition of the procedure is much larger than 8K. I need to print the entire text of a string that is larger than 8K.
I know SQL Server has a built-in script object feature. What I need to print may not be a database object: I need to print an arbitrary string.
Sometimes I have to generate very large scripts, so I had to solve the same problem. This is my solution:
Create a select where you add a line break at the end and let it be XML. The query options (right click in your query window, section "grid") allow to specify the maximum size of an XML in grid view, which is almost unlimited (limits by your hardware).
After clicking the XML you can copy and paste its content.
Just try it:
SELECT name + CHAR(13)+CHAR(10)
FROM sys.objects
FOR XML PATH(''),ROOT('x')

How to insert large string in SQL Server

I'm trying to insert a large string into a nvarchar(max) column, but after inserting I found, that string was cut. There was only 43601 characters stored.
What is wrong?
It stores complete string but when you use select statement SQL interface display only certain number of characters...you can try reading thru .NET/java or try getting data thru SubString().. you should see complete data...
Usually you'll take warning text like 'string or binary will be truncated' in a case of truncation during insert. If you didn't have such warning, then likely You've inserted data successfully.
To check it, you can cast your field with large data to XML type and then open it to ensure what it's been stored well.
Example:
SELECT TOP 1000 [id]
,CAST([text] AS XML)
FROM [AnomalyDetection].[dbo].[TableA]
Result:
And finally, click on data to open it in the editor

T-SQL Extract portion of xml or nvarchar(max) column matching pattern

I'd like to do something that I think is fairly trivial using T-SQL//SQL Server 2008 R2, but I can't seem to figure out a way.
If I were in Java, C#, C++, whatever, I would do:
Find position of first occurrance of '123' in string
Execute substring operation from that position getting next 50 characters
So, in SQL Server, I'd basically like:
Find all rows where column (X) contains said string (basically a
LIKE clause)
Return 50 characters from that column starting at the said string's location.
Can I do this somehow? I can cast an XML column to nvarchar(max), do a like operation, and do a substring operation, I don't know how to get the position of the said string in the column in the first place though.
Sample content requested in comment
CREATE TABLE SampleTable(xmlData xml);
Pretend the value is in one if SampleTable's xmlData column is as follows. I would like to, for debugging purposes, extract the string from the funny unicode Þ character forward 50 characters (or to the end of the file if that's less than 50).
<RootNode>
<Row>
<NestedNode1>
some text.
</NestedNode1>
<NestedNode2>
123456
</NestedNode2>
<NestedNode3>
Þ Some crazy name with unicode letters. Þ
</NestedNode3>
</Row>
</RootNode>
Are you looking for CHARINDEX?
;WITH CTE AS(
SELECT CAST (xmlData as nvarchar(max)) as X
FROM SampleTable
)
SELECT SUBSTRING(X,CHARINDEX(N'Þ',X),50) as [String]
FROM CTE
WHERE CHARINDEX(N'Þ',X)>0

Resources