ORA-29260 连不上 SMTP 是因数据库服务器出向网络不通,非密码或代码错误;须在DB服务器执行 telnet 或 openssl 验证端口连通性,并检查防火墙、SELinux、代理及SMTP中继配置。
UTL_SMTP.OPEN_CONNECTION 连不上?先查数据库服务器的出向网络
ora-29260 不是密码错,也不是代码写错,90% 是数据库服务器压根没通 smtp 端口。oracle 不走你本地机器的网络,只用 db server 自身的 outbound 路径。
实操建议:
- 登录数据库服务器操作系统(不是你的开发机),执行
telnet smtp.example.com 587或openssl s_client -connect smtp.example.com:465 -crlf - 超时?找运维确认防火墙策略、SELinux 是否限制
oracle用户发起 socket 连接、是否需配代理 - 企业环境常见情况:DB Server 禁外网,只允许连内部中继(如
mail-relay.internal:25),必须用这个地址和端口 - OCI Email Delivery 场景下,端点类似
smtp.email.me-dubai-1.oci.oraclecloud.com:587,必须带端口且启用 STARTTLS
认证失败报 ORA-29278?用户名、密码、协议三者必须对齐
错误信息里带 535 5.7.8 Authentication failed,表面是登录失败,实际常因三处不匹配:用户名格式、密码类型、加密握手方式。
实操建议:
- 用户名必须是完整邮箱地址(如
'user@company.com'),不能只写'user';OCI 场景下是 OCID 形式(如'ocid1.user.oc1.aaaaaaalgtwnjkell') - 密码必须是 SMTP 专用密码(非登录密码),QQ/163/阿里云等需在邮箱后台手动开启 SMTP 并生成;Gmail 需开两步验证后设应用专用密码
- 端口 465 要用
UTL_SMTP.OPEN_CONNECTION(host, port)+UTL_SMTP.START_TLS;端口 587 必须调UTL_SMTP.START_TLS,否则服务器拒绝认证 - 密码含
+、/等特殊字符时,先赋值给VARCHAR2变量再传入,避免 PL/SQL 字符串解析截断
中文主题乱码或附件名变问号?MIME 头必须手写合规
收件人看到主题是 =?UTF-8?B?5byg5LiJ?= 或附件名乱码,说明 MIME 头缺失、格式错或没声明编码方式。UTL_SMTP 不自动封装,全靠你写。
实操建议:
- 主题必须用
UTL_ENCODE.MIMEHEADER_ENCODE(12c+ 内置)处理,不要自己拼=?UTF-8?B?xxx?=;低版本可用UTL_ENCODE.BASE64_ENCODE+ 手动加头 - HTML 邮件第一行空行前必须写全头:
Content-Type: text/html; charset=UTF-8,缺一不可,否则 Outlook 当纯文本 - 附件名含中文,
Content-Disposition必须用filename*=UTF-8''xxx.pdf格式(注意两个单引号),写成filename="xxx.pdf"在多数客户端失效 - 正文含中文,若数据库字符集非 AL32UTF8,建议先转 RAW:
UTL_RAW.CAST_TO_RAW('中文内容'),再用UTL_SMTP.WRITE_RAW_DATA
发大附件或超长正文?别硬塞进 message 参数
UTL_MAIL 的 message 限 32767 字节,但 UTL_SMTP 没这限制——它靠分块写入。问题出在你是否真用了流式发送逻辑。
实操建议:
- 附件超过几 MB,别读进 VARCHAR2;用
UTL_FILE.FOPEN打开文件,循环UTL_FILE.READ+UTL_SMTP.WRITE_RAW_DATA分片发送 - 多附件时,每个附件前要写独立
--boundary和Content-Type/Content-Disposition头,结尾用--boundary-- - 正文超长,拆成多段
UTL_SMTP.WRITE_DATA调用,每段控制在 2000 字符内,避免中间出现 CRLF 被误判为 DATA 结束 - 所有二进制数据(PDF、Excel)必须 Base64 编码后写入,且
Content-Transfer-Encoding设为base64











