Selecting a binary into XML will be transformed to a base64
encoded string.
DECLARE @SomeString NVARCHAR(10)='abcdefg';
DECLARE @SomeBinary VARBINARY(MAX)=CAST(@SomeString AS VARBINARY(MAX));
DECLARE @Xml XML=(SELECT @SomeBinary FOR XML PATH('row'),ROOT('root'),TYPE);
SELECT @xml;
-- The Binary is implicitly converted to base64
<root>
<row>YQBiAGMAZABlAGYAZwA=</row>
</root>
--Reading this, will implicitly re-encode this:
SELECT CAST(@xml.value(N'(/root/row/text())[1]',N'varbinary(max)') AS NVARCHAR(MAX));
UPDATE
Your restriction to use FROM OPENXML
is something you really should discuss! If you were restricted to use a horse for your next far distance travel, you would discuss this too :-D
Your code above returns a base64
encoded value
SELECT @ks
returns
<data>SABlAGwAbABvAFcAbwByAGwAZAAhAA==</data>
Read this documentation about FROM OPENXML
and binary data (section K). The advice is: Use XML's .value()
method to convert this back!
EXEC sp_xml_preparedocument @hDoc OUTPUT, @ks
DECLARE @base64String AS NVARCHAR(MAX);
select @base64String = data
FROM OPENXML(@hdoc, '/',2)
WITH
(
data varbinary(max) 'data'
)
SELECT 'Target_data', @base64String, CAST(CAST(N'<x>' + @base64String + N'</x>' AS XML).value(N'.',N'varbinary(max)') AS NVARCHAR(MAX));
EXEC sp_xml_removedocument @hDoc;
This works, but is a rather stupid approach. Why not read the value directly out of your XML with the .value()
method? This is like a far-distance-travel with a horse and an aeroplane for the last mile...
FROM OPENXML
has a lot of restrictions, is slow, needs to parse the full XML whenever you need it, is not inlineable, not useable in a VIEW
or an iTVF
, clumsy, hard to read and - uhm - outdated.
UPDATE 2
In the comments I've told you already that your restrictions point to some absolutely outdated settings. You should rather change those...
If you have to stick with it, you might insert the binary value as hexString into your XML and use a dynamically created statement to get the value back:
DECLARE @hexString VARCHAR(1000)=master.sys.fn_varbintohexstr(CAST('Some text you want to convert!' AS VARBINARY(1000)));
SELECT @hexString;
DECLARE @cmd VARCHAR(MAX)='SELECT CAST(' + @hexString + ' AS VARCHAR(1000))';
EXEC(@cmd);
But this is a really ugly hack... Have to clean my hands now :-D