从作业执行的sp_send_dbmail失败,查询结果作为文件附加

时间:2013-02-27 13:05:33

标签: sql-server sql-server-2008 attachment sp-send-dbmail

我遇到了以下问题:当尝试发送带有查询结果作为文件的电子邮件时,通过执行普通查询使用 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'

有什么建议吗?

8 个答案:

答案 0 :(得分:26)

我已经解决了这个问题。不知道为什么它会起作用但从来没有。 :) 这绝对是关于安全的。

我已经调查过SQL代理是代表域用户运行的,例如 DOMAIN \ User 。 它在服务器上具有完整的管理员权限('sysadmin'服务器角色等)。 SQL Server本身在同一个用户下运行。

包含对 sp_send_dbmail 的调用的作业步骤在同一 DOMAIN \ User 下运行。

此外,我已经跟踪过,当运行 sp_send_dbmail 的查询部分时,它会尝试执行 exec xp_logininfo'mainAIN \ User',如果该用户没问,则检查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.

有一些概率可能意味着该用户的密码已过期或用户被锁定或该家伙的任何其他不愉快的事情。

我决定改变Agent的用户风险。所以我代表'sa'发送邮件,它具有相同的'sysadmin'服务器角色,但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

答案 1 :(得分:7)

我有这个问题。我正在使用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没有权限的某些表(实际上在我的情况下它甚至都没有权限)。

我通过SQLSMS添加了一个新用户" CONTROLLEDNETWO \ sql.service"到db" MYDB01"并授予"选择"。

的权限

答案 2 :(得分: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运行。在打开变量并尝试授予权限之后,我在作业的脚本中看到它仍在使用master数据库。我发现那个设置正盯着我。它位于Step的配置中。我将其更改为msdb并且工作正常。请记住,我已根据某些帖子将select从myTable更改为myDatabase.dbo.myTable。这可能有也可能没有帮助解决问题。我还使用了@execute_query_database来确保它从正确的位置运行查询。同样,这可能没有必要。

无论什么最终让它开心,它与它是否附着无关。

答案 3 :(得分:1)

在我的情况下,它无法识别表属于数据库。将database.dbo.table添加到查询后就可以了。

答案 4 :(得分:0)

手动执行查询时,会使用您的凭据。当SQL代理执行相同的查询时,将使用SQL代理服务帐户的凭据。默认情况下,SQL Server代理将使用LocalSystem帐户凭据。解决此问题的一种方法是使用可以访问csv目录\ file的用户更改运行SQL Server代理服务的用户。

答案 5 :(得分:0)

我认为此问题是由于SQL 2008及更高版本中实施的更改导致仅关闭sp_send_dbmail的安全性。 只有将qry传递给send_dbmail执行才会发生,并通过电子邮件返回结果。问题是错误消息具有误导性并且不合适。 一个好的解决方案是创建一个只具有执行该查询所需的最低权限的SQL用户。例如,db_reader,db_writer和db_owner,如果绝对必要的话。并使该用户成为所有者。您还可以创建SQL凭据并将该sql作业配置为在该SQL凭据下运行。

答案 6 :(得分:0)

我也有这个问题,并在这里使用了很多建议分两部分解决了。

1)右键单击,作业上的“查看历史记录”显示失败详细信息,失败通知给出了作业运行的用户名,因此我授予该用户对我的数据库的只读权限。

2)我忘记指定 DBName.dbo .MyTableName并且仅使用MyTableName。

顺便说一下,这些电子邮件都是我的垃圾邮件文件夹。

答案 7 :(得分:0)

这都非常有用,谢谢。想要分享我试图用excel(xls)附件做的事情,将结果放在列中。通过添加query_result_no_padding = 1和query_result_separator =',',这对我有用。 (这是一个Tab,Tab中的标签)

@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'