web-dev-qa-db-ja.com

SQLエージェントジョブ内でsp_send_dbmailが失敗するのはなぜですか?

アカウントが30日以上無効になっている場合に、ADアカウント管理者に電子メール通知を送信するために実行する簡単なクエリがあります。 SAとしてログインして自分で実行すると完全に正常に機能しますが、SQLServerエージェントジョブ内で実行すると失敗します。

以下は、ビジネス固有のアイテムとオブジェクト名を置き換えたクエリです。

DECLARE @QueryString varchar(max)
SET @QueryString = 'Select TrackingTable.Username FROM dbName.Schema.TrackingTable inner join dbName.Schema.viewName on DisabledAccounts.username = viewName.username WHERE DATEDIFF(dd,DateDisabled,GETDATE()) > 25 AND viewName.OU = ''InactiveAccounts'''
EXEC msdb.dbo.sp_send_dbmail  @profile_name = 'Profile', @body = 'This is the body text. Nothing interesting here.
', @recipients = '[email protected]', @subject='Account status update', @query = @QueryString, @importance = 'High'

SAとして実行すると、メッセージが送信されます。 SQL Serverエージェントジョブ内で、次のエラーが発生します。

Executed as user: DOMAIN\MemberOfDomainAdmins. Error formatting query, probably invalid parameters [SQLSTATE 42000] (Error 22050).  The step failed.

ジョブを実行するドメインユーザーには、msdbのdb_ownerロールと、メッセージに添付されたクエリに使用されるデータベースが割り当てられます。両方のデータベースのデフォルトのスキーマはdboです。

また、サーバーでsysadminロールが割り当てられ、msdbのDatabaseMailuserRoleのメンバーです。また、クエリで使用されるデータベースメールプロファイルへのプライベートアクセスとパブリックアクセスもあります。

オンラインで同じ問題の例を何十も見てきましたが、私が見た例では、この問題を解決するための手順をすでに実行しました。他に何を試すことができますか?

5
Ben Wyatt

私は今朝それを理解しました。問題はDATEADD関数にありました。 EXECUTEステートメント(SQL Serverエージェントジョブが実行する方法)内にある場合、間隔はトークン( "dd")の1つではなく、特定の日付部分(日)である必要があります。

したがって、この関数:DATEDIFF(dd,DateDisabled,GETDATE())

次のようにする必要があります:DATEDIFF(day,DateDisabled,GETDATE())

そこではその関数への複数の呼び出しがありましたが、あなたはその考えを理解します。

これが私がそれを理解した方法です:SQL Server Management Studioに、新しいクエリエディタードキュメントのCREATEスクリプトとしてジョブをスクリプト化させました。実行しようとしているステップを見つけたら、それをコピーしました。ジューシーなビットは次のようになります。

_@command = N'[my query]'_

その行のグループを新しいウィンドウにコピーし、コマンド変数にDECLAREを追加しました。

最後に、EXECUTE (@command) AS USER = '[the user the job runs as]'を使用して何が起こるかを確認しました。この方法でクエリを実行すると、ジョブのログから取得した方法よりもmuchより詳細なエラーメッセージが表示されました。

私は今それを修正しました、そして仕事は完全に実行されます。

6
Ben Wyatt