为什么sp_send_dbmail在SQL代理作业中失败?

我有一个简单的查询,当帐户被禁用30天以上时,我会运行它向我们的AD帐户pipe理员发送电子邮件通知。 当我自己运行它时,它工作得很好,以SA身份login,但在SQL Server代理作业中运行时失败。

以下是查询,replace了特定于业务的项目和对象名称:

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_ownerangular色,并将该数据库用于附加到该消息的查询。 它在两个数据库上的默认模式是dbo。

它还在服务器上分配了sysadminangular色,并且是msdb上DatabaseMailuserRole的成员。 它还具有私人和公共访问查询使用的数据库邮件configuration文件。

我在网上看到了几十个同样问题的例子,但是我已经在我看到的例子中采取了解决这个问题的步骤。 我还有什么可以尝试?

我今天早上想到了。 问题在于DATEADD函数。 当它位于EXECUTE语句(这是SQL Server代理作业如何运行它)内时,间隔必须是特定的date部分(date),而不是其中的一个标记(“dd”)。

所以,这个函数: DATEDIFF(dd,DateDisabled,GETDATE())

需要更像这样: DATEDIFF(day,DateDisabled,GETDATE())

那里有多个对这个函数的调用,但是你明白了。

下面是我如何计算出来的:在新的查询编辑器文档中,我将SQL Server Management Studio脚本作为CREATE脚本工作。 一旦我find了我试图运行的步骤,我就复制出来了。 多汁的东西看起来像这样:

@command = N'[my query]'

我将这组行复制到一个新的窗口,并为命令variables添加了一个DECLARE。

最后,我使用EXECUTE (@command) AS USER = '[the user the job runs as]'来看看会发生什么。 以这种方式运行查询,我得到比作业日志更详细的错误消息。

我现在已经纠正了,而且工作完美。