UTL_SMTP 包

UTL_SMTP 包的功能是提供对 smtp 服务器的基本访问请求以及通过 SMTP 服务器发送邮件的功能。

使用 UTL_SMTP 包发送邮件的大致流程为:首先,声明连接,并开启连接;其次,遵照 SMTP 协议与服务器进行握手,并根据 RFC821 简单邮件传输协议进行命令和邮件内容等的发送;最后,关闭会话,关闭连接。

35.1 相关方法

下面对各个函数和过程进行详细说明。

  1. connection

定义 connection 为 record 类型,为下面的过程或函数使用。

语法如下:

TYPE CONNECTION IS RECORD (
	REMOTE_HOST			VARCHAR2(255),
	REMOTE_PORT			INT,
	TX_TIMEOUT			INT,
	PRIVATE_HNDL		BIGINT
);

参数详解

  • Remote_host,remote_port

    为 smtp 服务器的地址及端口号,由 open_connection 过程传入。

  • tx_timeout

    为等待响应时间,同样由 open_connection 过程传入。

  • private_hndl

    为内部标识 connection 的 id。

  1. OPEN_CONNECTION

用于开启并返回与 SMTP 服务器的连接。

语法如下:

FUNCTION OPEN_CONNECTION (
	HOST        		IN  		VARCHAR2,
	PORT        		IN  		PLS_INTEGER DEFAULT 25,
	TX_TIMEOUT  		IN  		PLS_INTEGER DEFAULT NULL
)RETURN CONNECTION;

参数详解

  • host

    SMTP 服务器地址。

  • port

    SMTP 服务器端口号。

  • tx_timeout

    等待时间, NULL 代表一直等待,0 代表不等待。

  1. HELO/EHLO

用于向 SMTP 服务器打招呼。EHLO 指令表示需要 SMTP 认证,HELO 指令表示不需要 SMTP 认证。

语法如下:

PROCEDURE HELO (
	C       		IN OUT 		CONNECTION,
	R_DOMAIN  		IN          VARCHAR2
); 

或者

PROCEDURE EHLO (
	C       		IN OUT 		CONNECTION,
	R_DOMAIN  		IN          VARCHAR2
); 

参数详解

  • c

    使用的 SMTP 连接。

  1. COMMAND

用于向 smtp 服务器发送命令。命令不由此程序判断正确性,发送错误命令,程序会报错。

语法如下:

PROCEDURE COMMAND (
	C     		IN OUT 		CONNECTION,
	CMD   		IN          VARCHAR2,
	ARG   		IN       	VARCHAR2 DEFAULT NULL
);

参数详解

  • c

    使用的连接。

  • cmd 命令名

    准备登陆为 AUTH LOGIN(AUTH LOGIN 命令使用后,要分别再使用 command 发送用户名和密码);握手为 HELO;更多的命令详见 RFC821 简单邮件传输协议。

  • arg 命令参数

    可选参数,不同的 cmd 使用不同的 arg 。例如: AUTH LOGIN 无参数,但必须接下来继续使用 command 发送用户名和密码;而 HELO 后面的参数为服务器地址。

  1. MAIL

用于告知服务器发件人。

语法如下:

PROCEDURE MAIL (
	C           		IN OUT 			CONNECTION,
	SENDER      		IN           	VARCHAR2,
	M_PARAMETERS  		IN           	VARCHAR2 	DEFAULT NULL
);

参数详解

  • c

    使用的 SMTP 连接。

  • sender

    发件人邮箱。

  • m_parameters

    可选参数。公认的几种 SMTP 的扩展将会用到 MAIL FROM 和 RCPT TO 的额外参数,详见 RFC1869 第 6 部分,格式要求必须符合 "XXX=XXX (XXX=XXX
    ....)"。

  1. RCPT

用于告知 SMTP 服务器收件人信息。

语法如下:

PROCEDURE RCPT (
	C           		IN OUT 			CONNECTION,
	RECIPIENTS   		IN           	VARCHAR2,
	R_PARAMETERS  		IN          	VARCHAR2 	DEFAULT NULL
);

参数详解

  • c

    使用的 SMTP 连接。

  • recipients

    收件人邮箱。

  • r_parameters

    可选参数。公认的几种 SMTP 的扩展将会用到 MAIL FROM 和 RCPT TO 的额外参数,详见 RFC1869 第 6 部分,格式要求必须符合 "XXX=XXX (XXX=XXX
    ....)"。

  1. OPEN_DATA

用于告知 SMTP 服务器开始发送数据。只有使用过该过程才可以发送数据。

语法如下:

PROCEDURE OPEN_DATA (
	C			IN OUT		CONNECTION
);

参数详解

  • c

    使用的 SMTP 连接。

  1. WRITE_DATA

用于发送邮件内容(varchar 类型)。

语法如下:

PROCEDURE WRITE_DATA (
	C			IN OUT		CONNECTION, 
	DATA		IN			VARCHAR2
);

参数详解

  • c

    使用的 SMTP 连接。

  • data

    发送的内容,varchar 类型。

  1. WRITE_RAW_DATA

用来发送邮件内容(varbinary 类型)。

语法如下:

PROCEDURE WRITE_RAW_DATA (
	C     		IN OUT 		CONNECTION,
	DATA  		IN 			VARBINARY
);

参数详解

  • c

    使用的 SMTP 连接。

  • data

    邮件内容,varbinary 类型。

  1. CLOSE_DATA

关闭数据流,告知服务器数据发送完毕。

语法如下:

PROCEDURE CLOSE_DATA (
	C     		IN OUT 		CONNECTION
);

参数详解

  • C

    所使用 SMTP 连接。

  1. QUIT

用来结束会话。

语法如下:

PROCEDURE QUIT (
	C  			IN OUT 		CONNECTION
);

参数详解

  • c

    使用的 SMTP 连接。

  1. CLOSE_CONNECTION

关闭 SMTP 连接。

语法如下:

PROCEDURE CLOSE_CONNECTION (
	C     		IN OUT 		CONNECTION
);

参数详解

  • c

所需要关闭的 SMTP 连接。

35.2 应用实例

使用包内的过程和函数之前,如果还未创建过系统包,请先调用系统过程创建系统包。

SP_CREATE_SYSTEM_PACKAGES(1, 'UTL_SMTP');
SP_CREATE_SYSTEM_PACKAGES(1, 'UTL_TCP');
SP_CREATE_SYSTEM_PACKAGES(1, 'UTL_RAW');

举一个使用 UTL_SMTP 包发邮件的例子。发件人 yhx@dameng.shanghai,收件人 gyf@dameng.shanghai,发送内容为邮件头部信息(收件人、发件人、发送时间、主题、编码等),重复 10 次的 “达梦数据库第 i 行”。

DECLARE
  C UTL_SMTP.CONNECTION;	//声明连接
  MSG VARCHAR2(4000);
BEGIN
  C := UTL_SMTP.OPEN_CONNECTION('192.168.0.212');	//开启连接
  UTL_SMTP.HELO(C, '192.168.0.212');	//握手
  UTL_SMTP.COMMAND(C, 'AUTH LOGIN');	//准备登陆
  UTL_SMTP.COMMAND(C,UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW('yhx@DAMENG.SHANGHAI'))));	//用户名
  UTL_SMTP.COMMAND(C,UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW('888888'))));	//密码
  UTL_SMTP.MAIL(C, 'yhx@DAMENG.SHANGHAI');	//发件人
  UTL_SMTP.RCPT(C, 'GYF@DAMENG.SHANGHAI');	//收件人
  UTL_SMTP.OPEN_DATA(C);	//开始发送邮件内容
  MSG := 'CONTENT-TYPE: TEXT/PLAIN; CHARSET=GB2312' || UTL_TCP.CRLF || 'DATE:' ||
  TO_CHAR(SYSDATE, 'MM DD YYYY HH24:MI:SS') || UTL_TCP.CRLF || 'FROM:' ||
  'YHX@DAMENG.SHANGHAI' || UTL_TCP.CRLF || 'SUBJECT: HOW TO USE SMTP' || UTL_TCP.CRLF ||
  'TO: ' || 'GYF@DAMENG.SHANGHAI' ||  UTL_TCP.CRLF ||
  'CONTENT-TYPE: TEXT/PLAIN; CHARSET=GB2312' || UTL_TCP.CRLF ;
 	//MSG为邮件头信息, 邮件头信息需要与正文信息, 通过UTL_TCP.CRLF来分隔开
  UTL_SMTP.WRITE_RAW_DATA(C, UTL_RAW.CAST_TO_RAW(MSG));	//发送邮件头信息
  UTL_SMTP.WRITE_DATA(C, UTL_TCP.CRLF ||'达梦数据库SMTP包邮件示例:' || UTL_TCP.CRLF);	 //发送邮件正文信息
  FOR I IN 1 .. 10 LOOP
        UTL_SMTP.WRITE_DATA(C, '达梦数据库DM 第' || i || '行' || UTL_TCP.CRLF);
  END LOOP;
  UTL_SMTP.CLOSE_DATA(C);	//邮件内容发送完毕
  UTL_SMTP.QUIT(C);	//结束会话
  UTL_SMTP.CLOSE_CONNECTION(C);	//关闭连接
  END;

所收到的邮件内容(包含 msg 中所写的收件人,发件人,时间信息):

邮件内容.png

微信扫码
分享文档
扫一扫
联系客服