为什么在查询非xml数据的链接服务器时出现错误“分布式查询不支持Xml数据types”?

我有两个名为DATA01DATA02 SQL Server(运行SQL Server 2008)。 DATA02有一个链接的服务器定义LINK ,指向DATA01 ,并build立了合适的用户映射。 在DATA01有一个包含这两个表的数据库MyDatabase

 CREATE TABLE T_A ( Id int ) CREATE TABLE T_B ( Id int, Stuff xml ) 

当我从DATA02运行这个命令时,我得到的数据按预期返回:

 SELECT Id FROM LINK.MyDatabase.dbo.T_A; 

但是,当我从DATA02运行这个命令,我得到一个错误:

 SELECT Id, Stuff FROM LINK.MyDatabase.dbo.T_B; 

错误是

分布式查询不支持Xml数据types。 远程对象“DATA02.MyDatabase.dbo.T_B”具有xml列。

奇怪的是,这个命令:

 SELECT Id FROM LINK.MyDatabase.dbo.T_B; 

也给出了同样的错误, 即使我没有SELECT的XML列! 这是怎么回事?

这是SQL Server中的一个缺陷。 在表上只存在一个xml列防止它参与分布式查询(例如,通过链接的服务器连接查询)。 这在文档中提到 ,虽然不是特别显着。 您可以在这里看到主要的连接错误报告 ,以及类似的报告 。 后者给出了两个解决方法:

  1. 在远程服务器上创build没有XML列的[a]视图并查询。

    在你的例子中,这将涉及添加一个视图到MyDatabase看起来像这样:

     CREATE VIEW V_T_B AS SELECT Id FROM T_B; 

    然后你可以通过链接查询这个视图来获取Id数据。 请注意,像

     SELECT Id FROM ( SELECT Id FROM T_B ) T_B; 

    不起作用

  2. 在表单中使用传递查询

     SELECT * from OPENQUERY (... ) 

    这种方法的优点是不需要对源数据库进行任何更改; 缺点是不能再使用本地和链接数据的标准四部分命名。 查询将如下所示

     SELECT Id FROM OPENQUERY(DATA02, 'SELECT Id FROM T_B') T_B; 

    请注意,如果您确实需要xml数据,则将需要此方法(以及从非xml数据types转换而来)。

     SELECT Id, CAST(Stuff AS XML) Stuff FROM OPENQUERY(DATA02, 'SELECT Id, CAST(Stuff AS nvarchar(max)) Stuff FROM T_B') T_B; 

请注意,该错误是在SQL Server 2005中首次报告的,并且在SQL Server 2014中保持不变。

尝试这个:

  • 使用xml转换为nvarchar(max)在源端创build一个视图:

CREATE VIEW vXMLTest AS SELECT cast(作为nvarchar(max)的东西)与STUFF FROM T_B

  • 您可以在目标端select它,并将其转换为xml

SELECT(Cast as XML)as Stuff FROM OPENQUERY(DATA02,'SELECT Stuff FROM vXMLTest')

这个解决scheme适用于2008R2。