I spent all afternoon writing a remote routine based on XML parameter, including OUTPUT. Your post saved me a lot of headaches.
Thanks, Erland!
Erland Sommarskog wrote:
Re: exec linkedserver.dbo.forxml_proc: why do I receive "binary" data?
12-Jan-08
DC (dc@upsize.de) writes:
First why this happens: when FOR XML data is returned through OLE DB,
it is transmitted in a binary format which is more compact than the
text version. The client is assumed to be able to unpack this, and
indeed you can do this in an OLE DB client. However, the application
needs to know that FOR XML data is coming and use different API calls.
In this situation, the client is the calling SQL Server. But there is
no way to tell SQL Server "Hey, I will call a remote SP that emits FOR
XML, so do it right, will you?". (A similar problem exists with SQLCMD:
in SQLCMD if you use FOR XML you will just get a binary back. However,
SQLCMD has a mode switch to deal with the situation.)
When researching alternatives, I found that this was a little more
difficult that I thought. The first attempt was to convert the returned
binary data to xml as suggested by Rub?n. No, it is not that simple.
The next idea was to rewrite the procedure to have an output parameter
of the XML datatype. Alas, it is not supported to have output parameter
of LOB types (xml, varchar(MAX) etc) in remote procedure calls.
Eventually I arrived at this solution:
create procedure nisse as
declare @x varbinary(MAX)
set @x = convert(varbinary(MAX),
(select * from sys.objects for xml auto, type))
select @x
That is, add ", type" to the FOR XML clause, convert this to varbinary(MAX)
and return this. On the calling side:
create table #hh(a varbinary(MAX) NOT NULL)
insert #hh(a)
exec NOV07.tempdb.dbo.nisse
select convert(xml, a) from #hh
Use INSERT-EXEC to capture it and convert back to XML. Why the road over
varbinary(MAX)? Because XML is neither supported as result column in
remote queries.
The problem with this solution is that it requires you to rewrite the
procedure you call. If you cannot do this, I think your best option
is to write a CLR stored procedure that connects to the remote server,
possibly using the XmlReader to get the data. (It's not something I've
done myself, so I cannot offer any samples.)
--
Erland Sommarskog, SQL Server MVP, esquel.DeleteThis@sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
Previous Posts In This Thread:
On Saturday, January 12, 2008 7:57 AM
DC wrote:
exec linkedserver.dbo.forxml_proc: why do I receive "binary" data?
Hi,
I guess this is an old topic and I also tried to get an answer in
the ...xml group but to no avail - sorry for the repost. I have a
stored procedure "xmlproc" on "sqlserver_A", which returns xml via a
"select ... for xml auto" query. "sqlserver_B" is linked to
sqlserver_A (I tried to link as "SQL Server", "Native Client" and
"OLEDB") and calls
exec sqlserver_A.mydb.dbo.xmlproc
But instead of returning xml data, I receive a binary string that
looks like
0x440C690064005F0050006F0072007...
Is there anyway around this?
TIA, Regards
DC
On Saturday, January 12, 2008 9:29 AM
novalidaddres wrote:
?Have you tried to cast the binary data to an XML type?
?Have you tried to cast the binary data to an XML type?
--
Rub?n Garrig?s
Solid Quality Mentors
On Saturday, January 12, 2008 10:48 AM
Erland Sommarskog wrote:
Re: exec linkedserver.dbo.forxml_proc: why do I receive "binary" data?
DC (dc@upsize.de) writes:
First why this happens: when FOR XML data is returned through OLE DB,
it is transmitted in a binary format which is more compact than the
text version. The client is assumed to be able to unpack this, and
indeed you can do this in an OLE DB client. However, the application
needs to know that FOR XML data is coming and use different API calls.
In this situation, the client is the calling SQL Server. But there is
no way to tell SQL Server "Hey, I will call a remote SP that emits FOR
XML, so do it right, will you?". (A similar problem exists with SQLCMD:
in SQLCMD if you use FOR XML you will just get a binary back. However,
SQLCMD has a mode switch to deal with the situation.)
When researching alternatives, I found that this was a little more
difficult that I thought. The first attempt was to convert the returned
binary data to xml as suggested by Rub?n. No, it is not that simple.
The next idea was to rewrite the procedure to have an output parameter
of the XML datatype. Alas, it is not supported to have output parameter
of LOB types (xml, varchar(MAX) etc) in remote procedure calls.
Eventually I arrived at this solution:
create procedure nisse as
declare @x varbinary(MAX)
set @x = convert(varbinary(MAX),
(select * from sys.objects for xml auto, type))
select @x
That is, add ", type" to the FOR XML clause, convert this to varbinary(MAX)
and return this. On the calling side:
create table #hh(a varbinary(MAX) NOT NULL)
insert #hh(a)
exec NOV07.tempdb.dbo.nisse
select convert(xml, a) from #hh
Use INSERT-EXEC to capture it and convert back to XML. Why the road over
varbinary(MAX)? Because XML is neither supported as result column in
remote queries.
The problem with this solution is that it requires you to rewrite the
procedure you call. If you cannot do this, I think your best option
is to write a CLR stored procedure that connects to the remote server,
possibly using the XmlReader to get the data. (It's not something I've
done myself, so I cannot offer any samples.)
--
Erland Sommarskog, SQL Server MVP, esquel.DeleteThis@sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
On Tuesday, January 15, 2008 10:51 PM
DC wrote:
Re: exec linkedserver.dbo.forxml_proc: why do I receive "binary" data?
On 12 Jan., 16:48, Erland Sommarskog wrote:
)
)
chnol/sql/2005/downloads/books...
reviousversions/books.mspx- Zitierten Text ausblenden -
Thanks a ton, Erland! You did all the research that I had to do
otherwise. Since it is much more complicated than I thought, it is
probably a better idea to request a recordset and do the "for xml" on
the target server.
Regards
DC
Submitted via EggHeadCafe - Software Developer Portal of Choice
Join Lists with LINQ - SharePoint 2010
http://www.eggheadcafe.com/tutorials/aspnet/b0c1cd0d-fe82-444e-a16e-7d...7d38eca >> Stay informed about: exec linkedserver.dbo.forxml_proc: why do I receive ""binar..