xp_readmail (Transact-SQL)

阅读 SQL Mail 收件箱中的邮件。sp_processmail 使用此过程处理 SQL Mail 收件箱中的所有邮件。

注意注意

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

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

语法

xp_readmail [ [ @msg_id= ] 'message_id' ]
     [ , [ @type= ] 'type' [ OUTPUT ] ] 
     [ , [ @peek= ] 'peek' ]
     [ , [ @suppress_attach= ] 'suppress_attach' ]
     [ , [ @originator= ] 'sender' OUTPUT ]
     [ , [ @subject= ] 'subject' OUTPUT ]
     [ , [ @message= ] 'message' OUTPUT ]
     [ , [ @recipients= ] 'recipients [ ;...n ]' OUTPUT ]
     [ , [ @cc_list= ] 'copy_recipients [ ;...n ]' OUTPUT ]
     [ , [ @bcc_list= ] 'blind_copy_recipients [ ;...n ]' OUTPUT ]
     [ , [ @date_received= ] 'date' OUTPUT ]
     [ , [ @unread= ] 'unread_value' OUTPUT ]
     [ , [ @attachments= ] 'attachments [ ;...n ]' OUTPUT ])
     [ , [ @skip_bytes= ] bytes_to_skip OUTPUT ]
     [ , [ @msg_length= ] length_in_bytes OUTPUT ]
     [ , [ @originator_address= ] 'sender_address' OUTPUT ] ]

参数

  • [ @msg_id = ] 'message_id'
    要阅读的消息的 ID。message_id 的数据类型为 varchar(255),无默认值。

  • [ @type = ] 'type'
    根据以下 MAPI 定义返回的邮件类型:

    IP[ M|C ].Vendorname.subclass

    如果用于输入,则此参数必须定义特定邮件的类型;如果 message_id 为 NULL,则忽略输入的 type。type 的数据类型为 varchar(255),默认值为 NULL。SQL Mail 支持 IPM 和 IPC 邮件类型。

  • OUTPUT
    如果指定,则将指定参数值置于输出参数中。

  • [ @peek = ] 'peek'
    指示 SQL Server 是否返回邮件而不将邮件状态更改为已读。peek 的数据类型为 varchar(5),默认值为 FALSE。如果设置为 FALSE,则将邮件视为已读。如果设置为 TRUE,则将邮件视为未读。

  • [ @suppress_attach = ] 'suppress_attach'
    指示是否禁止邮件附件。suppress_attach的数据类型为 varchar(255),默认值为 FALSE。如果设置为 TRUE,则当 xp_readmail 读取带附件的邮件时,SQL Server 将禁止创建临时文件。如果设置为 FALSE,则读取带附件的邮件时,不禁止创建临时文件。

  • [ @originator = ] 'sender'
    返回的发件人邮件地址。sender的数据类型为 varchar(255),无默认值。

  • [ @subject=] 'subject'
    返回的邮件主题。subject 的数据类型为 varchar(255),无默认值。

  • [ @message=] 'message'
    返回邮件的正文或实际文本。message 的数据类型为 text,无默认值。

  • [ @recipients=] 'recipients [ ;...n] '
    要返回的邮件的收件人列表,以分号分隔。收件人的名称以分号 (
    ;
    ) 分隔。recipient_list 的数据类型为 varchar(255),无默认值。

  • [ @cc_list = ] 'copy_recipients [ ;...n] '
    要返回邮件的抄送字段中的收件人列表,以分号分隔。收件人的名称以分号 (
    ;
    ) 分隔。cc_list 的数据类型为 varchar(255),无默认值。

  • [ @bcc_list = ] 'blind_copy_recipients[ ;...n] '
    要返回的邮件在“密件抄送”字段中以分号分隔的收件人列表。收件人的名称以分号 (
    ;
    ) 分隔。bcc_list 的数据类型为 varchar(255),无默认值。如果电子邮件服务器不提供“密件抄送”字段的值,则 blind_copy_recipients 为空。

  • [ @date_received = ] 'date'
    邮件的返回日期。date 的数据类型为 varchar(255),无默认值。

  • [ @unread = ] 'unread_value'
    指示邮件以前是未读 (true) 还是已读 (false)。unread_value 的数据类型为 varchar(5),默认值为 TRUE。

  • [ @attachments = ] 'attachments [ ;... n] '
    返回的邮件附件的临时路径的列表,以分号分隔。临时路径以分号 (
    ;
    ) 分隔。attachments 的数据类型为 varchar(255),无默认值。

  • [ @skip_bytes = ] bytes_to_skipOUTPUT
    如果传递一个非零的值作为输入,则该参数指定在将邮件中后续的 255 字节(最大)读入 body_of_message 输出参数之前忽略的字节数。如果使用 bytes_to_skip,则 body_of_message 包含邮件的下一部分,bytes_to_skip 返回邮件中的下一个起点(上一个 bytes_to_skip 加上 message 的长度)。bytes_to_skip 的数据类型为 int,默认值为 0。

  • [ @msg_length = ] length_in_bytesOUTPUT
    以字节表示的邮件总长度。在存储过程中与 bytes_to_skip 一同使用时,该参数允许以 255 字节为单位成块读取文件。length_in_bytes 的数据类型为 int。

  • [ @originator_address = ] 'sender_address'
    已解析的邮件发件人地址。sender_address 的数据类型为 varchar(255),无默认值。

返回代码值

0(成功)或 1(失败)

结果集

xp_readmail 返回以下列的结果集。

列名

说明

Originator

电子邮件的发件人

Date Received

电子邮件的接收日期

Recipients

邮件的接收者

CC List

电子邮件“抄送”行中的接收者

BCC List

电子邮件“密件抄送”行中的接收者

Subject

电子邮件的主题行

Message

邮件的正文(文本)

Unread

该邮件是否未读

Attachments

邮件的任何附件

Message ID

Message ID

Type

邮件类型

注释

除无效参数外的任何问题都将记入 Microsoft Windows 应用程序日志。

使用 xp_readmail 的方法有两种:

  • 将收件箱内的全部邮件作为结果集返回客户端。

  • 阅读收件箱中的单封邮件。

若要将收件箱的内容作为结果集返回客户端,请不要指定任何输入参数。

如果未能成功地将 suppress_attach 参数的默认值更改为 TRUE,可能会导致两个与附件有关的安全问题。

  • 首先,如果两个不同的用户使用同一临时目录并登录到同一台计算机上,他们就可以互相查看对方的附件。可以通过检查 attachments 输出变量,来确定附件的存储位置以及两个用户是否共享了同一临时目录。

  • 其次,xp_deletemail 不会删除这些附件,因此您必须手动删除每封附件。

若要阅读收件箱中的单封邮件,应将 xp_findnextmsg 所返回的有效 message_id 提供给 xp_readmail 作为输入参数。您可以将 peek 和 suppress_attach 指定为输入参数,来控制邮件的阅读方式。将 peek 和 suppress_attach 用于此方法时,所有其他参数都是可选的输出参数,其中包含要阅读的邮件中的特定信息。

通过执行以下命令,可以查看将 xp_findnextmsg 用作 xp_readmail 的输入参数的示例:

sp_helptext 'sp_processmail';

用于阅读单封邮件时,xp_readmail 可以通过逐段阅读的方式阅读多于 255 个字节的邮件文本。使用 length_in_bytes 逐段阅读多于 255 个字节的邮件文本。将 length_in_bytes 同时作为输入参数和输出参数,可以编写循环代码,以处理整个邮件的文本。以下代码显示了这种循环的示例(假定 message_id 设置为 xp_findnextmsg 所返回的有效邮件标识符)。

USE master;
GO

-- Set up variables.

DECLARE @status INT,
        @message_part VARCHAR(255),
        @msg_id VARCHAR(255),
        @message_length INT,
        @skip_bytes INT,
        @message VARCHAR(MAX) ;

-- Find the next message

EXEC @status = dbo.xp_findnextmsg
     @msg_id = @msg_id OUTPUT ;


-- If xp_findnextmsg completed successfully and
-- there is a message in the inbox, read the message.

IF (@status = 0  AND @msg_id IS NOT NULL)
BEGIN
   WHILE (1=1)
   BEGIN
        EXEC @status = dbo.xp_readmail
             @msg_id = @msg_id,
             @msg_length = @message_length OUTPUT,
             @skip_bytes = @skip_bytes OUTPUT,
             @message = @message_part OUTPUT ;

        IF @status <> 0 BREAK ;

        SET @message = ISNULL(@message, '') + @message_part ;

        PRINT @message_length ;
        PRINT @skip_bytes;

        IF @message_length = @skip_bytes BREAK ;

    END ;
    
    IF @status = 0
    BEGIN
       SELECT 'Message ID' = @msg_id, 'Message Body' = @message ;
    END ;
    ELSE
        SELECT 'Could not read message.' ;
END;

GO

权限

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

示例

以下示例可返回阅读邮件时的状态。在此示例中,xp_findnextmsg 所返回的邮件 ID 值放置于局部变量 @message_id 中,并传递给 xp_readmail。

USE master ;
GO

DECLARE @status INT,
    @msg_id VARCHAR(255),
    @originator VARCHAR(255),
    @cc_list VARCHAR(255),
    @subject VARCHAR(255),
    @query VARCHAR(8000);


-- Find the next message

EXEC @status = dbo.xp_findnextmsg
     @msg_id = @msg_id OUTPUT ;


-- If xp_findnextmsg completed successfully and
-- there is a message in the inbox, read the message.

IF (@status = 0  AND @msg_id IS NOT NULL)
BEGIN
    EXEC @status = dbo.xp_readmail
        @msg_id = @msg_id,
        @originator = @originator OUTPUT,
        @cc_list = @cc_list OUTPUT,
        @subject = @subject OUTPUT,
        @message = @query OUTPUT,
        @peek = 'TRUE',
        @suppress_attach = 'TRUE'

END;
GO