2017-05-17 33 views
0

SQLマネージャーStudioでは、別のSQLサーバーへのリンクサーバーを作成しました。私が作成したリンクサーバーの名前は "linkedserver"です。リンクサーバーは、Microsoft OLE DBプロバイダーを使用します。ただし、他のプロバイダーでも以下の問題が発生します。直接リンクされたサーバーの照会openqueryを使用したVS照会

リモートSQLサーバには、スキーマ[schema]にデータベース[db]とテーブル[table]があります。 [table]には[column]と[column2]という2つの列があります。

リモートユーザーは、リモートユーザーのSQLユーザーに[読み取り専用]と[列2]の[列]のみがあります。問題は、下の例のようなデータをクエリしようとすると、[column2]はクエリに表示されませんが、私は[column2]でアクセスできないというエラーが発生します。私の回避策は、代わりにオープンクエリを作成することですが、これは便利ではありません。

-- Fetch one column via the linked server - DOES NOT WORK 
SELECT TOP 1 [column] 
FROM [linkedserver].[db].[schema].[table] 

最初の失敗したクエリのエラーメッセージは次のとおりです。OPENQUERYと回避策がある

Msg 2557, Level 16, State 7, Procedure sp_table_statistics2_rowset, Line 105 
User 'user' does not have permission to run DBCC SHOW_STATISTICS for object '[db].[schema].[table]'. 
Msg 230, Level 14, State 1, Procedure sp_table_statistics2_rowset, Line 105 
The SELECT permission was denied on the column 'column2' of the object 'table', database 'db', schema 'schema'. 

-- Fetch one column via the linked server through an openquery - WORKS 
SELECT * 
FROM OpenQuery (linkedserver 
'SELECT TOP 1 [column] 
FROM [db].[schema].[table]') 

あなたはこれを克服する方法を知っていますか、なぜこれが行われます?私の前提は、最初のクエリが[テーブル]のすべての列をフェッチしようとし、SQLマネージャスタジオでフィルタを適用することです。私はそれの権利ですか?何とかこの問題を克服できますか?

答えて

1

リンクサーバーでクエリを実行すると、sp_table_statistics2_rowsetがリンクサーバーで呼び出されます。

dbcc show_statistics(@qtbl, @statname) with stat_header join density_vector 

だからこれはあなたのリンクサーバー上のユーザーをSP実行するための権限を持っている必要があります:あなたは(ライン105)あなたはこのコードを見つけることができますが、コードを表示し、カーソルにする

exec sp_helptext 'sp_table_statistics2_rowset' 

を実行することができます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許可には、十分な が必要です。+すべての列に対してユーザーはすべての列に対するアクセス許可を持っている必要があります。 統計オブジェクト フィルタ条件(存在する場合)のすべての列に対して、テーブルに行レベルの セキュリティポリシーを設定することはできません。

あなたのサーバーのバージョンは> = 2012 SP1だと思うので、いくつかの列に権限がないため、ユーザーには要件が渡されません。 SQL Server 2008 R2を使用しているため問題が再現できません。古いDBプロバイダを使用し、SQLNCLI10を使用して別のリンクサーバーを作成し、問題が解決したかどうかをテストするようアドバイスできます。 dbcc権限を確認するリンク:https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-show-statistics-transact-sql

この記事では、TF9485を使用してこの動作を無効にすることができますが、dbccの実行に必要な権限に影響するかどうか、またはネイティブに影響するかどうかはわかりませんクライアントの行動も同様

+0

お返事ありがとうございます。プロパティを見ると、リモートサーバーのバージョンは "11.0.6567.0"と表示されます。残念ながら、私はリンクサーバーを作成したSQLサーバーにSQLNCLI10プロバイダーをインストールする権利がありません。 SQLNCLI11プロバイダーのみがインストールされています。あなたのソリューションは有望ですが、私はそれを試すことができたらいいと思う。 – aragorn

+0

SQL Server 2012 SP3のテーブルの1つの列に対するアクセス許可を持つユーザーと同じ状況を作成してエラーを再現しようとしました.2014年からのリンクを作成し、それ自体からループバックできませんでしたリンクされたサーバからの直接選択とopenqueryを使用して同じエラーを取得することはできませんが、そのユーザがターゲット2012でそのテーブルに対して直接sp_table_statistics2_rowsetを実行するとエラーが発生します。だから私はそれが重要なサーバーの正確なバージョンであるかどうかと私はそれを接続して検索すると、この項目を接続していると思っていた: – sepupic

+0

https://connect.microsoft.com/SQLServer/feedback/details/796349/distributed-query-fails-on-tables部分アクセスを伴う – sepupic

関連する問題