如何将存储过程查询结果完整传入SEND_MAIL的邮件正文?
解决Oracle存储过程邮件正文仅含最后一条记录的问题
你当前的存储过程存在两个关键问题,导致邮件正文只能拿到最后一条记录:
- 每次循环中直接用
:=给mail_body_v赋值,会覆盖之前的内容,而非追加 - 错误地将
DBMS_OUTPUT.PUT_LINE的结果赋值给变量,实际上DBMS_OUTPUT.PUT_LINE仅用于控制台输出,没有返回值,这行代码逻辑错误
修正方案
需要将每行日志内容追加到邮件正文字符串中,并添加换行符分隔每条记录,同时移除错误的DBMS_OUTPUT.PUT_LINE赋值逻辑。
修正后的完整代码
create OR REPLACE PROCEDURE EVAL_LOG AS mail_body_v varchar2(4000) := ''; -- 初始化空字符串 BEGIN FOR I IN ( select LOG.LOG_DATE, LOG.ACTION, LOG.OLD, LOG.NEW from dw.EVALUATIONS_LOG LOG where TRUNC(log_date) = (select TRUNC(max(log_date)) from dw.EVALUATIONS_LOG) ) loop -- 追加每行内容,用CHR(10)添加换行符 mail_body_v := mail_body_v || 'Date : ' || i.log_date || ' ACTION : ' || i.ACTION || ' OLD : ' || NVL(i.OLD, ' ') || -- 处理NULL值,避免显示空白 ' NEW : ' || NVL(i.NEW, ' ') || CHR(10); -- 换行符,适配邮件换行 end loop; -- 调用发送邮件存储过程(注意参数顺序匹配SEND_MAIL定义:mail_to, mail_from, mail_subject, mail_body, host) SEND_MAIL( '****@mailid.com', '****@mailid.com', 'Subject', mail_body_v, 'host' ); end; /
关键修改说明
- 初始化
mail_body_v为空字符串,确保从空白开始追加内容 - 使用
||运算符将每行内容追加到变量中,而非覆盖原有值 - 添加
CHR(10)作为换行符,让邮件正文每条记录单独一行 - 用
NVL处理OLD和NEW字段的NULL值,避免出现无内容的情况 - 修改日期过滤逻辑,用
TRUNC(log_date)替代to_char转换,更高效且避免格式兼容问题
预期效果
邮件正文将包含所有符合条件的日志记录,格式如下:
Date : 16-AUG-22 ACTION : INSERT OLD : NEW : 2382382 Date : 16-AUG-22 ACTION : UPDATE OLD : 175 NEW : 195 Date : 16-AUG-22 ACTION : INSERT OLD : NEW : 232323 Date : 16-AUG-22 ACTION : UPDATE OLD : 195 NEW : 175 Date : 16-AUG-22 ACTION : UPDATE OLD : 195 NEW : 175 Date : 16-AUG-22 ACTION : UPDATE OLD : 175 NEW : 195 Date : 16-AUG-22 ACTION : DELETE OLD : 232323 NEW :
内容的提问来源于stack exchange,提问作者Karthik Garimella
相关产品推荐
相关产品推荐

