SQL Server空间数据和联接服务器

24
我有一个SQL Server实例,我已经将另一个SQL实例添加为联接服务器。我要访问的联接服务器上的表包含空间类型。当我尝试查询该表时,我收到以下错误消息:

不允许在分布式查询中使用具有CLR类型列的对象。请使用透传查询访问远程对象。

如果我使用相同的查询和OPENQUERY,则会收到另一个错误如下:

当前命令发生严重错误。 如果有任何结果,则应放弃。

是否有任何方法可以通过联接服务器查询包含空间类型的表?
3个回答

19

解决这个问题的一种方法是将空间数据作为NVARCHAR(MAX)传递。

select go=geometry::STGeomFromText(go,0)
from openquery([other\instance],
'select go=convert(nvarchar(max),go) from tempdb.dbo.geom')

注意:go 是一个列名,代表几何对象。

或者使用函数而不是显式转换。

select go=geometry::STGeomFromText(go,0)
from openquery([other\instance],
'select go=go.STAsText() from tempdb.dbo.geom')

1
对于地理位置,使用:geography :: STGeomFromText(go,4326) - Aymeric Gaurat-Apelli

19

我遇到了同样的问题,但是接受的解决方案对我来说不是一个选项,因为有许多应用程序无法更改以期望完全不同的查询。

相反,我想我找到了一种欺骗系统的方法。在本地服务器上运行:

CREATE VIEW stage_table
AS
SELECT *
FROM OPENQUERY([REMOTESERVER],'SELECT * FROM [REMOTEDB].[SCHEMA].TARGET_TABLE');
GO
CREATE SYNONYM TARGET_TABLE FOR stage_table;
GO

看,现在你可以简单地使用它了

SELECT * FROM TARGET_TABLE;

这可能是您的应用程序所期望的。

尝试使用本地服务器:SQLEXPRESS 2008 R2和远程服务器SQL EXPRESS 2014进行上述情况。


我遇到了“不允许在分布式查询中公开具有CLR类型的列的对象。请使用经过传递的查询来访问远程对象”的提示:pkExec的提示解决了这个问题。 - AAsk
2
请明确以下内容。所需的确切转换如下。如果查询形式为select * from [remoteservername].[remotedatabasename].[schemaname].[tablename]失败,则只需将其替换为select * from OPENQUERY([remoteservername], 'select * from [remotedatabasename].[schemaname].[tablename]')。您基本上需要将远程服务器名称(即不是其域名或类似的任何名称...而是您链接的任意名称)移动到表标识符之外,并将其作为参数传递给openquery。 - Triynko
@Triynko 我的回答甚至涵盖了查询形式为“SELECT * FROM table_name”的情况。如果您使用您在评论中提到的内容,则对于空间数据类型,查询将失败(根据AAsk的评论)。 - pkExec
视图和同义词确实是可选的。 - jumxozizi
这个确实可以工作。但是请注意,如果您使用章鱼部署,它仍然会抛出错误。- Calamari.exe:Use-DatabaseReleaseArtifact:应用更新脚本失败:不允许暴露具有CLR类型的列的对象。 - drinky

7

我有另一个解决方法。这并不适用于OP的问题,因为他们试图选择空间数据。即使您没有选择包含空间数据的列,仍然会出现此错误。因此,如果您需要查询此类表格,并且不需要检索空间数据,则可以为该表格创建视图(仅选择所需列,排除空间数据列),然后针对该视图进行查询。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接