web-dev-qa-db-ja.com

リンクサーバーのクエリの実行がsp_send_dbmailで失敗する

次の例を見てください。

EXEC msdb.dbo.sp_send_dbmail 
@recipients = '[email protected]' ,
@query = 'SELECT TOP 10 * FROM LINKEDSERVERA.DATABASE.dbo.TABLE' ,
@attach_query_result_as_file = N'True' ,
@query_attachment_filename = 'test.txt' ,
@subject = 'test' ,
@body = 'test' ,
@body_format = 'HTML' ;

これにより、次のエラーが発生します(両方のサーバーに対するsysadmin特権を持つWindows資格情報で実行された場合でも)。

Msg 22050, Level 16, State 1, Line 0
Error formatting query, probably invalid parameters
Msg 14661, Level 16, State 1, Procedure sp_send_dbmail, Line 504
Query execution failed: OLE DB provider "SQLNCLI10" for linked server "LINKEDSERVERA" returned message "Login timeout expired".
OLE DB provider "SQLNCLI10" for linked server "LINKEDSERVERA" returned message "A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correc
t and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.".
HResult 0xFFFF, Level 16, State 1
SQL Server Network Interfaces: Error getting enabled protocols list from registry [xFFFFFFFF]. 

現在、問題のリンクサーバーは次のように構成されています(@useselfの使用とマッピングなし)。

EXEC master.dbo.sp_addlinkedserver @server = N'LINKEDSERVERA', @srvproduct=N'SQL Server'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'LINKEDSERVERA',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'collation compatible', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'data access', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'dist', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'pub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'rpc', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'rpc out', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'sub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'connect timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'collation name', @optvalue=null
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'lazy schema validation', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'query timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'use remote collation', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'LINKEDSERVERA', @optname=N'remote proc transaction promotion', @optvalue=N'true'

ここがファンキーになる場所です:SSMSで手動で(つまり、sp_send_dmail内ではなく)以下を実行すると、クエリは正常に実行されます!

SELECT TOP 10 * FROM LINKEDSERVERA.DATABASE.dbo.TABLE

したがって、リンクサーバーIS機能しており、そのsp_send_dmailで問題が発生しています。

そのため、次に、SQL Serverサービス(エージェントを含む)で使用されている資格情報に問題があると想定しました-これらは両方ともDOMAIN\SQLサービスアカウントとして実行されています-そのサービスアカウントとしてMSSMSにログインし、手動でクエリを実行する-再び機能しますそのため、サービスアカウントには、リンクサーバー上でクエリを実行するためのアクセス許可が確実にあります。

(両方のサーバーで)ネイティブクライアントで有効になっているプロトコルを再確認しましたTCPは両方のサーバーで確実に有効になっており、私が言うように、sp_send_dbmail内で実行されない場合は正常に動作します。

sp_send_dmailがサービスアカウントとしてクエリを実行していたことを確認するために、以下を実行しました(SYSTEM_USERの使用に注意してください)。

EXEC msdb.dbo.sp_send_dbmail 
@recipients = '[email protected]' ,
@query = 'SELECT SYSTEM_USER' ,
@subject = 'test' ,
@body = 'test'

これにより、DOMAIN\SQL資格が返されました。

エラーの最後の部分はレジストリについて何かについて言及していますが、それがsp_send_dbmailにのみ影響する理由がわかりません(レジストリで何をチェックする必要があるかについて100%確信しているわけではありません)–私が見つけた唯一の記事SQL 2005用であり、SQL 2008 R2ではキーの場所が異なるようです。

私の質問:このリンクサーバークエリをsp_send_dbmailの外部で正常に機能するようにするには、どうすればよいですか?

[〜#〜] ps [〜#〜]:記事 このように に異なる認証情報を提供することで問題を回避しますリンクサーバー-このリンクサーバーは他の何百ものクロスサーバークエリで使用され、すべて正常に機能しているため、これはオプションではありません。

同様の問題:

2013年5月17日編集:2週間後の5月3日にマイクロソフトに有料サポートリクエストを提出しましたが、彼らはまだそれを理解するのに苦労していますアウト、彼らは今、彼らの「SQLサーバー接続チーム」でそれを提起し、私はそれらにネットワークトラフィックの記録などに加えて両方のサーバーからSQLトレースを送信する必要がありました-マイクロソフトが私たちに戻ってきた場合と回答すると質問を更新します。

4
HeavenCore

さて、有料サポート経由でマイクロソフトに数十回電話をかけ、接続チームと1.5時間会話し、3週間の追跡を行った後、Promon分析と、これは既知の問題であると言われて驚いたことです。

https://connect.Microsoft.com/SQLServer/feedback/details/753426/dbmail-fails-when-using-a-linked-server-query

基本的に、MicrosoftはWindows認証とSQLネイティブクライアントを使用してDSNを作成することを勧めました。次に、そのODBC DSNセキュリティコンテキストを使用しないDSNを使用して2番目のリンクサーバーを作成する必要がありました-これは機能し、リモートクエリを正しいユーザーとして実行します。

マイクロソフトはこれを大規模な計画の小さな問題であるため、修正しません。

彼らは修正を見つけたら私に返答すると言っていましたが、私は息を止めません。

4
HeavenCore

ローカルサーバーに一時テーブルを作成し、クエリの結果を一時テーブルに読み込み、一時テーブルでsp_send_dbmail @queryを実行します。

編集:申し訳ありませんが、これは、sp_send_dbmail関数をリンクサーバー全体で機能させるためのソリューションではありませんが、回避策を提供できます。

2
Cougar9000

DBメールは外部サービスによって処理されます: DatabaseMail90.exe 。このサービスは、DOMAIN\SQL資格情報を使用してエンジンに接続します。このコンテキストは、sp_send_dbmail呼び出しで指定されたクエリを実行します。そのため、リンクサーバーにはサービスアカウントでは到達せず、接続されているアプリケーション(DatabaseMail90.exe)の偽装コンテキストで到達します。これは、サービスアカウントと同じアカウントです。 DatabaseMail90.exeが使用する正確な設定が何であるかはわかりませんが、Profilerがどのように接続するかを調べて、関連するものを見つけたかどうかを確認してください。

1
Remus Rusanu

HeavenCoreの回答が質問に答えます。ただし、セキュリティ上の欠陥なしにこれを回避する別の方法があります。

テーブルに出力を返し、DBmailでテーブルをクエリします。

1
Tigerjz32