SQL Server语言 - 从作业执行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'

有什么建议吗?

我已经找到了这个问题的解决方法。不知道为什么它会起作用,但绝不会少。 :)这绝对是关于安全的。

我已经调查了 SQL 代理代表域用户运行,例如域\用户。它在服务器上具有全套管理员权限("系统管理员"服务器角色等(。SQL Server 本身在同一用户下运行。

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

我还跟踪到,当运行sp_send_dbmail的查询部分时,它会尝试执行exec xp_logininfo"域\用户">以检查 Active Directory 是否该用户正常。令人惊讶的是:有些事情绝对不行。此检查最终为:

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

这很可能意味着有关该用户密码的任何内容已过期或用户被锁定或该人的任何其他不愉快的事情。

我决定为代理更改用户是有风险的。所以我代表"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

我遇到了这个问题。我正在使用 SQL Server 2008 R2。我收到了通过添加选项发送的电子邮件,其中包含有关错误的更多信息:

@append_query_error = 1,

我收到一封电子邮件,其中包含有关权限而不是我的查询的错误:

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

我的查询试图访问一些 SQL 代理没有权限的表(实际上在我的情况下它甚至无法访问它(。

我通过SQLSMS修复了它,方法是将新用户"CONTROLNETWO\sql.service"添加到数据库"MYDB01"并授予"选择"权限。

这一切都很有帮助,谢谢。想分享我试图用 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'
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'

作为参考,此操作失败了,反复显示为以域管理员身份调用,但以本地\sqladmin身份运行。在将变量从 on 中翻转并尝试授予权限后,我在作业脚本中看到它仍在使用 master 数据库。我发现环境正盯着我的脸。它位于步骤的配置中。我把它改成了msdb,它起作用了。请记住,我根据一些帖子将"从myTable中选择"更改为"从myDatabase.dbo.myTable中选择"。这可能有助于也可能没有帮助解决问题。我还使用 @execute_query_database 来确保它从正确的位置运行查询。同样,这可能没有必要。

不管最后是什么让它快乐,都与它是否依恋无关。

在我的

情况下,它无法识别该表属于数据库。一旦 database.dbo.table 被添加到查询中,它就可以工作了。

当您手动执行查询时,将使用您的凭据。当 SQL 代理执行相同的查询时,将使用 SQL 代理服务帐户的凭据。默认情况下,SQL Server 代理将使用本地系统帐户凭据。解决此问题的一种方法是使用有权访问 csv 目录\文件的用户更改运行 SQL Server 代理服务的用户。

我相信

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

我也遇到了这个问题,并使用这里的许多建议分两部分解决了它。

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

2(我忘了指定DBName.dbo。MyTableName,并且仅使用 MyTableName。

顺便说一句,这些电子邮件都去了我的垃圾邮件文件夹。

相关内容

  • 没有找到相关文章

最新更新