xp_sendmail (Transact-SQL)

将可能包含查询结果集附件的电子邮件发送给指定的收件人。此扩展存储过程使用 SQL Mail 发送邮件。

注意注意

后续版本的 Microsoft SQL Server 将删除该功能。 请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。 若要从 SQL Server 发送邮件,请使用 数据库邮件

主题链接图标Transact-SQL 语法约定

语法

xp_sendmail { [ @recipients= ] 'recipients [ ;...n ]' } 
     [ ,[ @message= ] 'message' ] 
     [ ,[ @query= ] 'query' ] 
     [ ,[ @attachments= ] 'attachments [ ;...n ]' ] 
     [ ,[ @copy_recipients= ] 'copy_recipients [ ;...n ]'
     [ ,[ @blind_copy_recipients= ] 'blind_copy_recipients [ ;...n ]'
     [ ,[ @subject= ] 'subject' ]
     [ ,[ @type= ] 'type' ] 
     [ ,[ @attach_results= ] 'attach_value' ]
     [ ,[ @no_output= ] 'output_value' ] 
     [ ,[ @no_header= ] 'header_value' ] 
     [ ,[ @width= ] width ] 
     [ ,[ @separator= ] 'separator' ] 
     [ ,[ @echo_error= ] 'echo_value' ] 
     [ ,[ @set_user= ] 'user' ] 
     [ ,[ @dbuse= ] 'database' ]

参数

  • [ @recipients=] **'**recipients [ ;...n] '
    以分号分隔的邮件收件人列表。

  • [ @message=] 'message'
    要发送的邮件正文。message 最大可达 8,000 个字节。

  • [ @query=] 'query'
    有效的 SQL Server 查询,其结果通过电子邮件发送。xp_sendmail 对 query 参数使用绑定连接。SQL Mail 建立的 query 连接不会被发出 xp_sendmail 请求的客户端所控制的锁阻塞。这使 xp_sendmail 更易于在触发器中使用。但 query 语句不能引用 inserteddeleted 逻辑表,因为这些表只在触发器中可用。query 最大可达 8,000 个字节。

  • [ @attachments=] **'**attachments [ ;...n] '
    以分号分隔的附加到邮件的文件列表。如果在 @attach_results 为 TRUE 时使用 @query 参数,则 @attachments 参数只能指定一个要附加到邮件中的文件。在这种情况下,若要发送多个文件,必须为每个附件文件分别运行 xp_sendmail

  • [ @copy_recipients=] **'**copy_recipients [ ;...n] '
    以分号分隔的列表,标识邮件副本收件人。

  • [ @blind_copy_recipients=] **'**blind_copy_recipients[ ;...n] '
    可选的以分号分隔的列表,标识邮件密件副本收件人。

  • [ @subject=] 'subject'
    指定邮件主题的参数。如果未指定 subject,则默认值为“SQL Server 消息”。

  • [ @type = ] 'type'
    基于以下 MAPI 邮件定义的输入邮件类型:

    IP[ M|C ].Vendorname.subclass

    如果 type 为 NULL,则 xp_sendmail 使用 IPM 邮件类型。以 IPM 开头的邮件类型显示在邮件客户端的收件箱中,通过 xp_findnextmsg 可以查找或读取这些邮件类型。以 IPC 开头的邮件类型不会显示在邮件客户端的收件箱中,必须通过设置 type 参数来查找或读取。默认值为 NULL。SQL Mail 支持 IPM 和 IPC 邮件类型。

  • [ @attach_results=] 'attach_value'
    可选参数,指定查询结果集应作为邮件中的附件文件发送,而不是追加到邮件中发送。如果 @attachments 不为 NULL,并且 @attach_results 为 TRUE,则 attachments 中的第一个文件名将作为结果集的文件名。如果 @attachments 为 NULL,则生成带 .txt 扩展名的文件名。默认值为 FALSE,这意味着结果集将追加到邮件中。

  • [ @no_output=] 'output_value'
    可选参数,用来发送邮件但不向发送邮件的客户端会话返回任何输出。默认值为 FALSE,这意味着 SQL Server 客户端会话将接收输出。

  • [ @no_header=] 'header_value'
    可选参数,表示通过邮件发送查询结果,但不随查询结果发送列标头信息。默认值为 FALSE,即列标头信息随查询结果一起发送。

  • [ @width=] width
    可选参数,设置查询的输出文本行宽。此参数与 isql 实用工具中的 /w 参数相同。对于产生长输出行的查询,应结合使用 width 与 attach_results,以发送行中无换行符的输出。默认宽度为 80 个字符。

  • [ @separator=] 'separator'
    结果集中每列的列分隔符字符串。默认情况,列分隔符为空格。使用列分隔符可以使分析电子表格和其他应用程序中的结果集变得更加容易。例如,结合使用 separator 与 attach_results,以发送用逗号分隔值的文件。

  • [ @echo_error=] 'echo_value'
    该值为 TRUE 时,SQL Mail 将捕获运行查询时遇到的任何服务器消息或 DB-Library 错误,并将其追加到邮件中而不是写入错误日志。同时也将返回行/受影响行的计数追加到邮件中。

    注意注意

    echo_error 为 TRUE 时,即使出现 DB-Library 错误或消息或查询没有返回结果,只要邮件成功发送,xp_sendmail 就返回状态 0(成功)。

  • [ @set_user=] 'user'
    是应在其中运行查询的安全上下文。如果没有指定 user,则安全上下文默认为运行 xp_sendmail 的用户的安全上下文。

  • [ @dbuse=] 'database'
    是应在其中运行查询的数据库上下文。默认值为 NULL,这意味着将用户置于默认数据库中。

返回代码值

0(成功)或 1(失败)

结果集

成功时,xp_sendmail 将返回一条消息。

注释

SQL Mail 会话必须在运行 xp_sendmail 之前启动。会话可以自动启动,也可以使用 xp_startmail 启动。有关如何自动设置 SQL Mail 会话的详细信息,请参阅配置扩展 MAPI 邮件配置文件。一个 SQL Mail 会话支持 SQL Server 实例的所有用户,但每次只有一个用户可以发送邮件。其他发送邮件的用户自动排队等候,直到第一个用户的邮件发送出去。

如果指定 query,则 xp_sendmail 作为客户端登录到 SQL Server,并运行指定的查询。SQL Mail 建立与 SQL Server 之间的单独的连接;它不与发出 xp_sendmail 的原始客户端连接共享同一连接。

注意注意

发出 xp_sendmail 的客户端连接所控制的锁会阻塞 query。例如,如果要在事务中更新表,并且为更新创建了触发器,而该触发器试图选择的更新行信息与 query 参数所选择的相同,则 SQL Mail 连接将被初始客户端连接所控制的行排他锁阻塞。

xp_sendmail 在 SQL Server 的安全上下文中运行。有效 xp_sendmail 用户可以在管理员安全上下文中访问邮件的附件文件。如果非系统管理员用户必须访问 xp_sendmail,而您希望阻止对附件文件的不安全访问,则系统管理员可以创建一个存储过程,该过程调用 xp_sendmail 并提供所需的功能,但不公开 attachments 参数。此存储过程必须在 master 数据库中定义。然后系统管理员可向必要的用户授予该存储过程的执行权限,但不授予基础 xp_sendmail 过程的权限。

xp_sendmail 向指定收件人发送邮件、查询结果集或附件,并对 query 参数使用绑定连接。SQL Mail 建立的 query 连接不会被发出 xp_sendmail 请求的客户端所控制的锁阻塞。这使 xp_sendmail 更易于在触发器中使用。但是,query 语句不能引用仅在触发器中可用的逻辑 inserted 和 deleted 表。

注意注意

当邮局和通讯簿位于 MSSQLServer 服务因无足够权限而无法访问的文件共享位置时,试图运行 xp_sendmail 将导致违规访问。

xp_sendmail 不完全支持 xml 数据类型。使用 xml 数据类型的查询的格式可能不正确。使用数据库邮件发送包含 xml 数据的电子邮件。

权限

要求具有 sysadmin 固定服务器角色的成员身份,但也可以将 EXECUTE 权限授予其他用户。不过,出于安全考虑,建议将此存储过程的权限仅授予 sysadmin 固定服务器角色的成员。

示例

A. 向单个收件人发送邮件

以下示例向用户 Dan Wilson(电子邮件地址是 danw)发送邮件,告知该用户 master 数据库已满。

EXEC master.dbo.xp_sendmail 
    @recipients=N'danw@Adventure-Works.com',
    @message=N'The master database is full.' ;

B. 向多个收件人发送邮件

以下示例将向用户 Dan Wilson 和 Ashvini Sharma(电子邮件地址为 ashvinis)发送邮件,并抄送给 Peter Connelly(电子邮件地址为 peterc)。该示例还指定了邮件的主题行。

EXEC master.dbo.xp_sendmail 
    @recipients=N'danw@Adventure-Works.com;ashvinis@Adventure-Works.com',
     @message=N'The master database is full.',
     @copy_recipients=N'peterc@Adventure-Works.com',
     @subject=N'Master database status' ;
GO

C. 发送结果

以下示例将 sp_configure 的结果发送给 Dan Wilson。

EXEC master.dbo.xp_sendmail 
    @recipients=N'danw@Adventure-Works.com',
    @query = N'EXEC sp_configure' ;
GO

D. 将结果作为附件文件发送

以下示例将查询 SELECT * FROM INFORMATION_SCHEMA.TABLES 的结果作为文本文件附件发送给 Dan Wilson。该示例包含邮件的主题行以及将在附件之前出现的邮件正文。@width 参数用于防止在输出行中换行。

EXEC master.dbo.xp_sendmail
    @recipients = N'danw@Adventure-Works.com', 
    @query = N'SELECT * FROM INFORMATION_SCHEMA.TABLES',
    @subject = N'SQL Server Report',
    @message = N'The contents of INFORMATION_SCHEMA.TABLES:',
    @attach_results = 'TRUE',
    @width = 250 ;

E. 发送大于 7,990 个字节字符的邮件

以下示例显示如何发送大于 7,990 个字节字符的邮件。由于 message 受 VARCHAR 长度的限制(这样每行开销较小,像所有存储过程参数一样),该示例将长消息写入由单个文本列组成的全局临时表中。然后使用 @query 参数通过邮件发送该临时表的内容。

CREATE TABLE ##mail_body(c1 NVARCHAR(4000)) ;

DECLARE @cmd VARCHAR(56) ;

INSERT ##mail_body(c1)
VALUES ('Put your long message here.') ;

SET @cmd = 'SELECT c1 FROM ##mail_body' ;

EXEC master.dbo.xp_sendmail 
    @recipients = 'danw@Adventure-Works.com', 
    @query = @cmd,
    @no_header= 'TRUE' ;

DROP TABLE ##mail_body ;