在SQL Server Management Studio中,我创建了一个到另一个SQL Server的链接服务器。我创建的链接服务器的名称是“linkedserver”。链接服务器使用Microsoft OLE DB提供程序。但是,下面描述的问题也发生在其他提供商处。
在远程SQL服务器中,架构[schema]中有一个数据库[db]和一个表[table]。 [table]有两列,[column]和[column2]。
我在远程SQL服务器中有一个SQL用户'user',它只具有读权限,仅适用于[column]但不适用于[column2]。问题是,当我尝试查询下面的示例数据时,我得到一个我在[column2]中无法访问的错误,尽管[column2]没有出现在查询中。我的工作是创建openqueries,但这不方便。
-- Fetch one column via the linked server - DOES NOT WORK
SELECT TOP 1 [column]
FROM [linkedserver].[db].[schema].[table]
第一个失败查询的错误消息是:
Msg 2557,Level 16,State 7,Procedure sp_table_statistics2_rowset,Line 105
用户'user'无权为对象'[db]。[schema]运行DBCC SHOW_STATISTICS。[table]'。Msg 230,Level 14,State 1,Procedure sp_table_statistics2_rowset,Line 105
对象'table'的列'column2',数据库'db',架构'schema'上的SELECT权限被拒绝。
openquery的解决方法是:
-- Fetch one column via the linked server through an openquery - WORKS
SELECT *
FROM OpenQuery (linkedserver
'SELECT TOP 1 [column]
FROM [db].[schema].[table]')
你知道如何克服这个问题,或者为什么要这样做?我的假设是第一个查询尝试获取[table]的所有列并在SQL Manager Studio中应用过滤器。我是对的吗?我能以某种方式克服这个问题吗?
答案 0 :(得分:1)
在链接服务器上执行查询时,将在链接服务器上调用sp_table_statistics2_rowset。你可以执行
exec sp_helptext 'sp_table_statistics2_rowset'
要查看代码,请在光标(第105行)中找到此代码:
dbcc show_statistics(@qtbl, @statname) with stat_header join density_vector
因此,为了执行此sp,链接服务器上的用户必须具有执行dbcc show_statistics的权限,这对于不同版本的SQL Server来说是不一样的。在SQL Server 2012 SP1之前,要求是“用户必须拥有该表,或者用户必须是sysadmin固定服务器角色,db_owner固定数据库角色或db_ddladmin固定数据库角色的成员”,并且大多数情况并非如此。情况(当用户不是链接服务器上的db_owner时),因此旧提供程序以静默方式使用此错误,并在不使用统计信息的情况下优化查询。 SQL Server 2012 SP1更改了行为,所需的权限更改如下:
SQL Server 2012 SP1修改权限限制并允许 具有SELECT权限的用户可以使用此命令。请注意 以下要求存在SELECT权限就足够了 运行命令:+用户必须拥有所有列的权限 统计对象用户必须拥有a中所有列的权限 过滤条件(如果存在)表不能具有行级 安全政策。
所以我认为您的服务器版本是> = 2012 SP1,并且您的用户未通过要求,因为他对某些列没有权限。 我无法重现您的问题,因为我的SQL Server 2008 R2您的案例运作良好,所以我建议您使用旧的数据库提供程序,使用SQLNCLI10创建另一个链接服务器并测试问题是否已消失。 检查dbcc权限的链接:https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-show-statistics-transact-sql
本文说您可以使用TF9485关闭此行为,但我不知道它是否会影响执行dbcc所需的权限,或者它也会影响本机客户端行为