web-dev-qa-db-ja.com

ジョブから実行されたsp_send_dbmailが失敗し、クエリ結果がファイルとして添付されます

私は次の問題に直面しました:クエリの結果をファイルとして添付してメールを送信しようとすると、通常のクエリを実行してsp_send_dbmailを使用すると、すべてが正常に動作しているようです。

ただし、同じコードをJobStepに追加してジョブを実行すると、失敗します。

ジョブ履歴のエラーは言う

クエリのフォーマットエラー、おそらく無効なパラメーター[SQLSTATE 42000](エラー22050)。ステップが失敗しました。

しかし、添付ファイルを参照するパラメーターをコメントアウトすると、再び正しく機能し始めます。

exec msdb.dbo.sp_send_dbmail 
    @profile_name = 'profile_name', 
    @recipients  = '[email protected]',
    @body = 'body',
    @subject = 'subj',
    --Parameters that refers to attached file
    @attach_query_result_as_file = 1, 
    @query_result_header = 0,
    @query_result_no_padding = 1,
    @query = 'select 1',
    @query_attachment_filename = 'test.csv'

助言がありますか?

17
Paul Kyrejto

私はその問題を回避するようになりました。なぜそれが機能するのかはわかりませんが、それでも劣りません。 :)それは間違いなくセキュリティについてです。

DOMAIN\Userのように、SQLエージェントがドメインユーザーに代わって実行されていることを調査しました。サーバーの管理者権限の完全なセット(「sysadmin」サーバーロールなど)があります。 SQL Server自体は同じユーザーで実行されています。

sp_send_dbmailへの呼び出しを含むジョブのステップは、同じDOMAIN\Userの下で実行されます。

また、sp_send_dbmailのクエリ部分を実行するときに、exec xp_logininfo 'DOMAIN\User'を実行して、そのユーザーがOKかどうかをActive Directoryでチェックすることもトレースしました。そして驚き:間違いなく何かは大丈夫ではありません。このチェックは次のようになります。

Msg 15404, Level 16, State 19, Server SQLC002INS02\SQLC002INS02, Line 1
Could not obtain information about Windows NT group/user 'DOMAIN\User.', error code 0x2.

つまり、ある程度の確率で、そのユーザーのパスワードの有効期限が切れているか、ユーザーがロックされているか、その男にとって他の不快なことを意味する可能性があります。

エージェントのユーザーを変更するのは危険だと判断しました。そこで、同じ「sysadmin」サーバーロールを持ち、SQL承認を持ち、このADチェック手順を省略した「sa」に代わってメールを送信することにしました。

管理者のふりをして、実際の管理者に危険なコードを実行するように頼むユーザーのように見えます:)

したがって、このジョブの最終コードは最初で唯一のステップです。

execute as login = 'sa'
exec msdb.dbo.sp_send_dbmail 
    @profile_name = 'profile_name', 
    @recipients  = '[email protected]',
    @body = 'body',
    @subject = 'subj',
    --Parameters that refers to attached file
    @attach_query_result_as_file = 1, 
    @query_result_header = 0,
    @query_result_no_padding = 1,
    @query = 'select 1',
    @query_attachment_filename = 'test.csv'
revert
26
Paul Kyrejto

この問題がありました。 SQL Server 2008 R2を使用しています。オプションを追加して、エラーに関する詳細を記載したメールを送信しました。

@append_query_error = 1,

クエリではなく、アクセス許可に関する次のエラーを含むメールを受け取りました。

   Msg 916, Level 14, State 1, Server SERVER\INST01, 
Procedure GetSalesReport, Line 62
The server principal "CONTROLLEDNETWO\sql.service" is not able 
to access the database "MYDB01" under the current security co
ntext.

私のクエリは、SQL Agentにアクセス許可がないテーブルにアクセスしようとしました(実際には、私の場合、アクセスすることさえできません)。

新しいユーザー "CONTROLLEDNETWO\sql.service"をデータベース "MYDB01"に追加し、 "select"へのアクセス許可を付与することにより、SQLSMSで修正しました。

7
Rafa
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = 'Main Profile',
    @recipients = '[email protected]',
    @subject = 'Test',
    @body = 'this is a test',
    @execute_query_database = 'myTargetDatabase_mscrm',
    @query = N'SELECT * from myTargetDatabase_mscrm.dbo.SystemUserBase',
    @attach_query_result_as_file = 1,
    @query_attachment_filename = 'Test.txt'

参考のため、これはドメイン管理者として呼び出されたものとして繰り返し表示されませんでしたが、local\sqladminとして実行されました。変数をオンからオフに切り替えて許可を与えようとした後、ジョブのスクリプトで、まだmasterデータベースを使用していることがわかりました。私は顔を凝視する設定を見つけました。ステップの構成にあります。私はそれをmsdbに変更しました。いくつかの投稿に基づいて、myTableからの選択をmyDatabase.dbo.myTableからの選択に変更したことに注意してください。それは問題の修正に貢献したかもしれないし、貢献していないかもしれない。また、@ execute_query_databaseを使用して、適切な場所からクエリを実行していることを確認しました。繰り返しますが、それは必要ではなかったかもしれません。

最終的に何が幸せになったとしても、それがアタッチされているかどうかとは何の関係もありませんでした。

1
Eric Hula

私の状況では、データベースが属するテーブルを特定できませんでした。 database.dbo.tableがクエリに追加されると、機能しました。

1
SQLguest

これはすべて役に立ちました、ありがとう。結果を列に配置したExcel(xls)添付ファイルで私がやろうとしていたことを共有したかった。これは、query_result_no_padding = 1、query_result_separator = '、'を追加することで機能しました。 (それは目盛りのタブ、タブです)

@query_result_header= 1,
@attach_query_result_as_file = 1,
@query_result_no_padding = 1,
@query_attachment_filename = 'TestPriceFlingerReport.xls',
@query_result_separator= '  ,   ',
@profile_name = 'Test Exchange Server'
0
Dan Pullman

私もこの問題を抱えており、ここでのアドバイスの多くを使用して2つの部分で解決しました。

1)ジョブの「履歴の表示」を右クリックすると、失敗の詳細が表示され、失敗通知にはジョブが実行されたユーザーの名前が示されたため、このユーザーにDBへの読み取り専用アクセス権を与えました。

2)DBName.dbo。MyTableNameを指定するのを忘れていて、MyTableNameのみを使用していました。

ちなみに、電子メールはすべて私の迷惑メールフォルダーに送信されていました。

0
Resource

この問題は、sp_send_dbmailのみのセキュリティをロックダウンすることに関して、SQL 2008以降で実装された変更によるものだと思います。 qryをsend_dbmailに渡して実行し、メールで結果を返す場合にのみ発生します。問題は、エラーメッセージが紛らわしく、適切でないことです。適切な解決策は、そのクエリを実行するために最低限必要な権限を持つSQLユーザーを作成することです。たとえば、db_reader、db_writer、および絶対に必要な場合はdb_owner。そして、そのユーザーを所有者にします。 SQL資格情報を作成し、そのSQL資格情報で実行するようにそのSQLジョブを構成することもできます。

0
user2238156

クエリを手動で実行すると、資格情報が使用されます。 SQLエージェントが同じクエリを実行すると、SQLエージェントサービスアカウントの資格情報が使用されます。既定では、SQL ServerエージェントはLocalSystemアカウントの資格情報を使用します。問題を解決する1つの方法は、csvディレクトリ\ファイルにアクセスできるユーザーでSQL Serverエージェントサービスを実行しているユーザーを変更することです。

0
David Brabant