19

次の問題に直面しました:通常のクエリを実行してsp_send_dbmailを使用すると、クエリの結果がファイルとして添付された電子メールを送信しようとすると、すべてが正常に機能しているように見えます。

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

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

クエリのフォーマット中にエラーが発生しました。パラメータが無効である可能性があります [SQLSTATE 42000] (エラー 22050)。ステップは失敗しました。

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

exec msdb.dbo.sp_send_dbmail 
    @profile_name = 'profile_name', 
    @recipients  = 'some@mail.com',
    @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'

助言がありますか?

4

8 に答える 8

31

私はその問題の回避策に来ました。なぜそれが機能するのかはわかりませんが、決して少なくはありません。:) それは間違いなくセキュリティに関するものです。

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

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

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

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」サーバー ロールを持つ「sa」に代わってメールを送信することになりましたが、SQL 承認があり、この AD チェック手順を省略しています。

管理者のふりをしているユーザーが、本当の管理者に危険なコードを実行するように依頼しているようです :)

したがって、このジョブの最初で唯一のステップの最終的なコードは次のようになります。

execute as login = 'sa'
exec msdb.dbo.sp_send_dbmail 
    @profile_name = 'profile_name', 
    @recipients  = 'some@mail.com',
    @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
于 2013-02-28T13:02:47.357 に答える
9

この問題がありました。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 エージェントがアクセス許可を持っていないいくつかのテーブルにアクセスしようとしていました (実際、私の場合はアクセスさえしていません)。

新しいユーザー「CONTROLLEDNETWO\sql.service」をデータベース「MYDB01」に追加し、「select」に権限を付与することにより、SQLSMSで修正しました。

于 2014-11-10T17:33:05.890 に答える
1
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = 'Main Profile',
    @recipients = 'me@vwp.com',
    @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 として実行されました。変数をオフにして許可を与えようとした後、ジョブのスクリプトでマスター データベースをまだ使用していることを確認しました。その設定が私の顔を見つめているのを見つけました。ステップの構成にあります。私はそれをmsdbに変更しましたが、うまくいきました。いくつかの投稿に基づいて、select from myTable を select from myDatabase.dbo.myTable に変更したことに注意してください。それが問題の解決に貢献したかもしれないし、貢献しなかったかもしれません。また、@execute_query_database を使用して、適切な場所からクエリが実行されていることを確認しました。繰り返しますが、それは必要ではなかったかもしれません。

最終的に何が喜ばれたとしても、愛着があるかどうかは関係ありません。

于 2016-08-22T21:02:25.813 に答える
0

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

于 2013-02-27T13:17:32.227 に答える
0

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

于 2015-06-30T22:32:44.183 に答える