在Oracle PL/SQL中格式化回车和换行

3

我有关于发送邮件正文格式的问题:

这是KO版本(没有换行):

declare
  crlf                     VARCHAR2(2) := chr(13)||chr(10); 
  msg_body                 VARCHAR2(2000);
begin
  msg_body := msg_body || ('Blablah  : '|| SYSTIMESTAMP ) || crlf;
  msg_body := msg_body || ('Blablah  : '|| SYSTIMESTAMP ) || crlf;
  EXECUTE IMMEDIATE 'ALTER SESSION SET smtp_out_server = ''127.0.0.1''';
  UTL_MAIL.send(sender => 'xx@xx.com', recipients => 'yy@yy.com', subject => 'Blah', MESSAGE => msg_body);
end;

这是OK版本(好的新行):
declare
  crlf                     VARCHAR2(2) := chr(13)||chr(10);
  msg_body                 VARCHAR2(2000);
begin
  msg_body := msg_body || ('Blablah  : ') || crlf;
  msg_body := msg_body || ('Blablah  : ') || crlf;
  EXECUTE IMMEDIATE 'ALTER SESSION SET smtp_out_server = ''127.0.0.1''';
  UTL_MAIL.send(sender => 'xx@xx.com', recipients => 'yy@yy.com', subject => 'Blah', MESSAGE => msg_body);
end;

最好的问候


1
你有什么问题吗?你的Ok版本可行吗? - jim mcnamara
1个回答

6
你的两个版本唯一的区别在于一个版本中排除了SYSTIMESTAMP。
你没有明确使用TO_CHAR()将SYSTIMESTAMP转换为字符。它将根据你的NLS_DATE_FORMAT进行隐式转换。
正确地将其转换为字符,可以使用任何格式模型;例如:
to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss:ff3')

ff 是毫秒。

引用

Oracle建议您指定显式转换,而不是依赖隐式或自动转换,原因如下:

  • 当您使用显式数据类型转换函数时,SQL语句更易于理解。

  • 隐式数据类型转换可能会对性能产生负面影响,特别是如果列值的数据类型转换为常量的数据类型,而不是相反的情况。

  • 隐式转换取决于它发生的上下文,并且在每种情况下可能不起作用。例如,从日期时间值到VARCHAR2值的隐式转换可能会根据NLS_DATE_FORMAT参数的值返回意外的年份。

  • 隐式转换算法可能会在软件发布之间和Oracle产品之间发生变化。显式转换的行为更可预测。


我建议研究使用 UTL_SMTP 而不是 UTL_MAIL。您无需更改会话。一个非常简单的发送过程可能如下所示:
declare

   l_to_list  long;
   l_crlf varchar2(2) := chr(13) || chr(10);
   l_conn utl_smtp.connection;
   l_date     varchar2(255) default to_char(sysdate, 'dd Mon yyyy hh24:mi:ss');

begin

   l_conn := utl_smtp.open_connection(<mailhost>, 25);
   utl_smtp.helo(l_conn, <mailhost>);
   utl_smtp.mail(l_conn, <sender>);

   l_to_list := address_email('To: ', <recipients>);

   utl_smtp.open_data(l_conn);

   utl_smtp.write_data('Date: ' || l_date);
   utl_smtp.write_data('From: ' || <sender>);
   utl_smtp.write_data('Subject: ' || nvl(<subject>, '(No Subject)'));
   utl_smtp.write_data('X-Mailer: ' || <mailer_id>);

   utl_smtp.write_data(l_to_list);

   utl_smtp.write_data(l_conn, '' || l_crlf);
   utl_smtp.write_data(l_conn, <msg>);
   utl_smtp.close_data(l_conn);
   utl_smtp.quit(l_conn);

end;

现在它作为一个PL/SQL块工作。to_char(systimestamp[...])做到了这一点。不幸的是,这段代码位于存储过程中,并且格式又被搞砸了 :/ - BenoitParis
@BenoitParis,你之前确切地找出了问题,并且可以再次做到!先寻找一些你隐式转换的东西(如日期/时间戳等),然后看看它是否有效... - Ben
谢谢。我解决了这个问题,但是忘记在这里发布了。我在正文中发送了长字符串,显然这导致格式被忘记。将回车之间的字符串缩短就解决了问题。也许有与长字符串相关的隐藏转换。 - BenoitParis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接