xp_readmail (Transact-SQL)
阅读 SQL Mail 收件箱中的邮件。sp_processmail 使用此过程处理 SQL Mail 收件箱中的所有邮件。
注意 |
---|
后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。 |
语法
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