Sql server 为什么我会得到这个错误;“分布式查询中不支持Xml数据类型”;在查询链接服务器的非xml数据时?
我有两台SQL Server(运行SQL Server 2008),分别名为Sql server 为什么我会得到这个错误;“分布式查询中不支持Xml数据类型”;在查询链接服务器的非xml数据时?,sql-server,xml,linked-server,Sql Server,Xml,Linked Server,我有两台SQL Server(运行SQL Server 2008),分别名为DATA01和DATA02DATA02有一个链接服务器定义LINK,指向DATA01,并设置了适当的用户映射。在DATA01上有一个数据库MyDatabase,包含以下两个表: CREATE TABLE T_A ( Id int ) CREATE TABLE T_B ( Id int, Stuff xml ) 当我从DATA02运行此命令时,我得到了预期返回的数据: SELECT Id FRO
DATA01
和DATA02
DATA02
有一个链接服务器定义LINK
,指向DATA01
,并设置了适当的用户映射。在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数据类型。远程对象“DATA02.MyDatabase.dbo.T_B”具有xml列
奇怪的是,这个命令:
SELECT Id FROM LINK.MyDatabase.dbo.T_B;
也给出了相同的错误,即使我没有选择xml列发生了什么事?这是SQL Server内部的一个缺陷。表上仅存在一个xml列,这就阻止了它参与分布式查询(例如通过链接的服务器连接进行查询)。这当前版本的文档中似乎没有提到这一点 过去,Microsoft Connect上有相关的bug报告,但现在这些报告已经“退役”,取而代之的是Azure反馈论坛。在结束时,会有一条指示“请直接从产品文档中提交反馈”,如果产品文档中确实提到了这一点,就可以了。包括从Connect迁移的评论,状态为“未计划” 以前存在的一个Connect bug报告提供了两种解决方法:
MyDatabase
看起来是这样的:
CREATE VIEW V_T_B AS SELECT Id FROM T_B;
然后,您可以通过链接查询此视图以获取Id
数据。注意
SELECT Id FROM ( SELECT Id FROM T_B ) T_B;
不起作用
SELECT Id FROM OPENQUERY(DATA02, 'SELECT Id FROM T_B') T_B;
请注意,如果您确实需要xml数据,则此方法(以及
与非xml数据类型之间的转换)将需要:
- 在源端创建一个视图,将xml转换为nvarchar(最大):
- 您可以使用cast-to-xml在目标端选择它
这个解决方案在2008年R2对我有效。我找到了另一种方法:
DATA01
、DATA02
甚至第三台服务器(可能是本地服务器)上创建一个链接服务器
EXEC[linked\u server].[sp\u sqlexecute]
执行查询OPENQUERY
sp\u sqlexecute
语法()将参数传递给查询。对于OPENQUERY
,必须传递字符串
或文本_LEX
,这意味着必须将所有值直接键入此函数DECLARE @UserID UNIQUEIDENTIFIER = ''
DECLARE @SearchForUserParams NVARCHAR(MAX) = N'@UserID UNIQUEIDENTIFIER';
DECLARE @SearchForUserQuery NVARCHAR(MAX) =
N'SELECT
UserID,
Username,
Email,
CONVERT(NVARCHAR(MAX), UserDataXml) AS UserDataXml
FROM User
WHERE UserID = @UserID
'
EXEC [linked_server].[dbo].[sp_executesql]
@SearchForUserQuery,
@SearchForUserParams,
@UserID = @UserID
您还可以在DATA02上创建一个存储过程,并远程调用该存储过程,而不是尝试远程运行查询。当我在本地数据库上创建视图时,从远程数据库表的select id得到相同的错误…SQL SERVER 2008 R2here@RMiranda必须在远程数据库上创建视图,然后从本地数据库中,您应该能够通过链接查询该视图。多么简单的解决方案!ThanksJust在SQL 2019中偶然发现了它(作为连接服务器)。也许这只是一个被误解的功能。好主意!非常好。当您需要从生产服务器获取一些数据并且无法创建视图时,这是一个很好的答案。但在您的示例中,您忘记了数据库:[linked_server].[database].dbo.[sp_executesql]…当我尝试此操作时,会出现一个错误:没有为RPC配置服务器“MySVR\MyDB”。配置链接服务器时,您需要在属性窗格中打开RPC和RPC。
SELECT Id, CAST(Stuff AS XML) Stuff
FROM OPENQUERY(DATA02, 'SELECT Id, CAST(Stuff AS nvarchar(max)) Stuff
FROM T_B') T_B;
DECLARE @UserID UNIQUEIDENTIFIER = ''
DECLARE @SearchForUserParams NVARCHAR(MAX) = N'@UserID UNIQUEIDENTIFIER';
DECLARE @SearchForUserQuery NVARCHAR(MAX) =
N'SELECT
UserID,
Username,
Email,
CONVERT(NVARCHAR(MAX), UserDataXml) AS UserDataXml
FROM User
WHERE UserID = @UserID
'
EXEC [linked_server].[dbo].[sp_executesql]
@SearchForUserQuery,
@SearchForUserParams,
@UserID = @UserID