如何将选择查询的结果发送到oracle 10G中邮件的消息正文
Posted
技术标签:
【中文标题】如何将选择查询的结果发送到oracle 10G中邮件的消息正文【英文标题】:How to send the result of a select query to a message body of a mail in oracle 10G 【发布时间】:2013-08-13 07:20:28 【问题描述】: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 在执行上述过程时,请帮助我....
【问题讨论】:
您想将employee
表中的所有记录发送到v_msg_body
变量中?
是的,上面的查询只返回 42 行,并且都必须传递给“v_msg_body”变量。
【参考方案1】:
所以实际上你真正的问题是:“如何将多行聚合成一个字符串?”
答案是使用aggregate functions。 Oracle 在 11gR2 中引入了listagg
-function,很好地解决了这个问题,但在早期版本中,我们需要做更多的工作。
当您知道正确的关键字时,Google 会找到大量优质资源,例如
String Aggregation Techniques listagg function in 11g release 2 the collect function in 10g我从上述资源中收集了以下示例。希望这能给您一个好的起点:
要查询的表:
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;
/
请注意,如果聚合字符串不适合保留的 varchar2
容量,我将如何捕获将引发的 value_error
异常。
两个例子的输出:
key = 1 value = a
key = 2 value = b
key = 3 value = c
【讨论】:
以上是关于如何将选择查询的结果发送到oracle 10G中邮件的消息正文的主要内容,如果未能解决你的问题,请参考以下文章