如何将选择查询的结果发送到oracle 10G中邮件的邮件正文

时间:2013-08-13 07:20:29

标签: stored-procedures plsql oracle10g

CREATE OR REPLACE PROCEDURE STATUS_MAIL(FROM_MAIL IN VARCHAR2, TO_MAIL IN VARCHAR2)
is
  v_From      VARCHAR2(80) := FROM_MAIL;
  v_Recipient VARCHAR2(80) := TO_MAIL;
  v_Subject   VARCHAR2(80) := 'EMPLOYEE STATUS';
  v_Mail_Host VARCHAR2(30) := 'xx.xx.xxx.xxx';
  v_Mail_Conn utl_smtp.Connection;
  v_msg_body VARCHAR2(5000);
  v_output VARCHAR2(5000);

BEGIN 
 /*Result always returns 42 rows*/
 v_output := 'select empid,ename,mobile,dept from employee';
 EXECUTE IMMEDIATE v_output into v_msg_body;

 v_Mail_Conn := utl_smtp.Open_Connection(v_Mail_Host, xx);
 utl_smtp.Helo(v_Mail_Conn, v_Mail_Host);
 utl_smtp.Mail(v_Mail_Conn, v_From);
 utl_smtp.Rcpt(v_Mail_Conn, v_Recipient);
 utl_smtp.Data(v_Mail_Conn,
   'Date: '   || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || UTL_TCP.crlf ||
   'From: '   || v_From || UTL_TCP.crlf ||
   'Subject: '|| v_Subject || UTL_TCP.crlf ||
   'To: '     || v_Recipient || UTL_TCP.crlf ||
   UTL_TCP.crlf || v_msg_body );
 utl_smtp.Quit(v_mail_conn);
EXCEPTION
 WHEN utl_smtp.Transient_Error OR utl_smtp.Permanent_Error then
 raise_application_error(-20000, 'Unable to send mail: '||sqlerrm);
END;

获取错误不一致的数据类型 @ EXECUTE IMMEDIATE v_output到v_msg_body 在执行上述程序时,请帮助我......

1 个答案:

答案 0 :(得分:3)

所以实际上你真正的问题是:“如何将多行聚合成一个字符串?”

答案是使用aggregate functions。 Oracle已经在11gR2中引入了listagg - 函数,很好地解决了这个问题,但在早期的版本中,我们需要做更多的工作。

当您知道正确的关键字时,Google会找到大量优质资源,例如

我从上述资源中收集了以下示例。希望这能给你一个很好的起点:

将被查询的表:

create table foo (d1 number, d2 varchar2(10));
insert all
into foo values(1, 'a')
into foo values(2, 'b')
into foo values(3, 'c')
select 1 from dual;
commit;

Oracle 11gR2:

declare
  v_str varchar2(32767);
begin
  select listagg('key = ' || d1 || ' value = ' || d2, chr(10))
  within group (order by d1)
    into v_str
    from foo;

  dbms_output.put_line(v_str);
exception
  when value_error then
    dbms_output.put_line('Exception: trying to insert too many characters to a varchar2 variable.');
end;
/

Oracle 10g:

create or replace type str_list_t as table of varchar2(32676);
/

create function to_string (
  nt_in        in str_list_t,
  delimiter_in in varchar2 default ','
) return varchar2 is
  v_idx pls_integer;
  v_str varchar2(32767);
  v_dlm varchar2(10);
begin
  v_idx := nt_in.first;
  while v_idx is not null loop
    v_str := v_str || v_dlm || nt_in(v_idx);
    v_dlm := delimiter_in;
    v_idx := nt_in.next(v_idx);
  end loop;

  return v_str;
end;
/

declare
  v_str varchar2(32676);
begin
  select to_string(cast(collect('key = ' || d1 || ' value = ' || d2) as str_list_t), chr(10))
    into v_str
    from foo;
  dbms_output.put_line(v_str);
exception
  when value_error then
    dbms_output.put_line('Exception: trying to insert too many characters to a varchar2 variable.');
end;
/

请注意,如果聚合字符串不适合保留的value_error容量,我将如何捕获varchar2异常。

两个示例的输出:

key = 1 value = a
key = 2 value = b
key = 3 value = c