Aak*_*shM 57 xml sql-server linked-server
我有两个SQL服务器(运行SQL Server 2008)命名DATA01和DATA02.DATA02具有链接的服务器定义LINK,指向DATA01适当的用户映射设置.在DATA01那里有一个MyDatabase包含这两个表的数据库:
CREATE TABLE T_A (
Id int
)
CREATE TABLE T_B (
Id int,
Stuff xml
)
Run Code Online (Sandbox Code Playgroud)
当我从中运行此命令时DATA02,我按预期返回数据:
SELECT Id FROM LINK.MyDatabase.dbo.T_A;
Run Code Online (Sandbox Code Playgroud)
但是,当我运行此命令时DATA02,我收到一个错误:
SELECT Id, Stuff FROM LINK.MyDatabase.dbo.T_B;
Run Code Online (Sandbox Code Playgroud)
错误是
分布式查询不支持Xml数据类型.远程对象'DATA02.MyDatabase.dbo.T_B'具有xml列.
奇怪的是,这个命令:
SELECT Id FROM LINK.MyDatabase.dbo.T_B;
Run Code Online (Sandbox Code Playgroud)
即使我不是SELECTxml列,也会出现同样的错误!这是怎么回事?
Aak*_*shM 92
这是SQL Server中的一个缺陷.表上仅存在 xml列会阻止它参与分布式查询(例如,通过链接服务器连接查询).这在文档中提到,但并不是特别突出.您可以在此处查看主要的Connect错误报告,以及此处的类似报告.后者提供了两种解决方法:
在远程服务器上创建没有XML列的[a]视图并查询它.
在您的示例中,这将涉及添加一个视图MyDatabase
,如下所示:
CREATE VIEW V_T_B AS SELECT Id FROM T_B;
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过链接查询此视图以获取Id
数据.请注意类似的东西
SELECT Id FROM ( SELECT Id FROM T_B ) T_B;
Run Code Online (Sandbox Code Playgroud)
不起作用.
在表单中使用传递查询
Run Code Online (Sandbox Code Playgroud)SELECT * from OPENQUERY (... )
该方法的优点是不需要对源数据库进行任何更改; 缺点是不再可能为本地和链接数据使用标准的四部分命名.查询看起来像
SELECT Id FROM OPENQUERY(DATA02, 'SELECT Id FROM T_B') T_B;
Run Code Online (Sandbox Code Playgroud)
请注意,如果你真的这样做需要的XML数据,这种方法(用铸造和从非XML数据类型一起)将需要:
SELECT Id, CAST(Stuff AS XML) Stuff
FROM OPENQUERY(DATA02, 'SELECT Id, CAST(Stuff AS nvarchar(max)) Stuff
FROM T_B') T_B;
Run Code Online (Sandbox Code Playgroud)请注意,该错误首先在SQL Server 2005中报告,并在SQL Server 2014中保持不变.
Csa*_*nár 10
试试这个:
CREATE VIEW vXMLTest AS SELECT cast(Stuff as nvarchar(max))为STUFF FROM T_B
SELECT Cast(Stuff as XML)作为OPENQUERY的东西(DATA02,'SELECT Stuff FROM vXMLTest')
这个解决方案适用于2008R2.
我找到了另一种方法:
Linked Serveron DATA01,DATA02甚至是第三个服务器(可能是本地的)。EXEC [linked_server].[sp_executesql]。为什么我更喜欢这种方法而不是创建视图或使用OPENQUERY?
sp_executesql语法将参数传递给您的查询(在此处找到有关 sp_sqlexecute 的更多信息)。因为OPENQUERY你必须传递一个STRINGor TEXT_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
Run Code Online (Sandbox Code Playgroud)