我有一个问题,我正在创建一个CLOB变量,其中包含oracle中查询的内容以通过电子邮件发送给用户,问题是它以.csv的形式发送电子邮件但没有内容。我找不到问题:
CREATE OR REPLACE PROCEDURE trackekr(cursor1 IN OUT SYS_REFCURSOR)
AS
v_connection UTL_SMTP.connection;
v_clob CLOB := EMPTY_CLOB();
v_len INTEGER;
v_index INTEGER;
c_mime_boundary CONSTANT VARCHAR2(256) := 'the boundary can be almost anything';
rec NUMBER(10, 0) := 0;
d_id NUMBER(10, 0) := 0;
customer VARCHAR2(20);
wife VARCHAR2(20);
date_rec DATE;
special_h VARCHAR2(20);
g_amount NUMBER(10, 0) := 0;
credit_amount NUMBER(10, 0) := 0;
a_number VARCHAR2(20);
a__name VARCHAR2(20);
BEGIN
OPEN cursor1 FOR
SELECT rec,
d_id,
customer,
wife,
date_rec,
special h,
g_amount
FROM (your query here);
WHILE cursor1%NOTFOUND
LOOP
FETCH cursor1
INTO rec,
d_id,
customer,
wife,
date_rec,
special_h,
g_amount,
credit_amount,
a_number,
a__name;
v_clob :=
v_clob
|| rec
|| ','
|| d_id
|| ','
|| customer
|| ','
|| wife
|| ','
|| date_rec
|| ','
|| special_h
|| ','
|| g_amount
|| ','
|| credit_amount
|| ','
|| a_number
|| ','
|| a__name
|| UTL_TCP.crlf;
END LOOP;
-- UTL
v_connection := UTL_SMTP.open_connection(mailhost, 25);
SMTP server name or ip address
UTL_SMTP.helo(v_connection, mail.exchange.mydomain.com);
UTL_SMTP.mail(v_connection, 'mylogin.Exchange.mydomain.com');
UTL_SMTP.rcpt(v_connection, 'mylogin.Exchange.mydomain.com');
UTL_SMTP.open_data(v_connection);
UTL_SMTP.write_data(v_connection, 'From: ' || 'mylogin.Exchange.mydomain.com' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, 'To: ' || 'mylogin.Exchange.mydomain.com' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, 'Subject: test subject' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, 'MIME-Version: 1.0' || UTL_TCP.crlf);
UTL_SMTP.write_data(
v_connection,
'Content-Type: multipart/mixed; boundary="' || c_mime_boundary || '"' || UTL_TCP.crlf
);
UTL_SMTP.write_data(v_connection, UTL_TCP.crlf);
UTL_SMTP.write_data(
v_connection,
'This is a multi-part message in MIME format.' || UTL_TCP.crlf
);
UTL_SMTP.write_data(v_connection, '--' || c_mime_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, 'Content-Type: text/plain' || UTL_TCP.crlf);
-- Set up attachment header
UTL_SMTP.write_data(
v_connection,
'Content-Disposition: attachment; filename="' || 'FIRSTFILE.csv' || '"' || UTL_TCP.crlf
);
UTL_SMTP.write_data(v_connection, UTL_TCP.crlf);
-- Write attachment contents
v_len := DBMS_LOB.getlength(v_clob);
v_index := 1;
WHILE v_index <= v_len
LOOP
UTL_SMTP.write_data(v_connection, DBMS_LOB.SUBSTR(v_clob, 32000, v_index));
v_index := v_index + 32000;
END LOOP;
-- End attachment
UTL_SMTP.write_data(v_connection, UTL_TCP.crlf);
UTL_SMTP.write_data(v_connection, '--' || c_mime_boundary || '--' || UTL_TCP.crlf);
UTL_SMTP.close_data(v_connection);
UTL_SMTP.quit(v_connection);
END;
正如我所说,它通过电子邮件发送.csv文件但是空了。
答案 0 :(得分:0)
请注意代码中的这一部分:
WHILE cursor1%NOTFOUND
永远不会对非空数据集执行循环。请改用:
WHILE cursor1%FOUND
甚至更好地使用隐式游标:
FOR cursor1 in
(SELECT rec,
d_id,
customer,
wife,
date_rec,
special_h,
g_amount,
credit_amount,
a_number,
a__name
FROM (your query here))
LOOP
v_clob :=
v_clob
|| cursor1.rec
|| ','
|| cursor1.d_id
|| ','
|| cursor1.customer
|| ','
|| cursor1.wife
|| ','
|| cursor1.date_rec
|| ','
|| cursor1.special_h
|| ','
|| cursor1.g_amount
|| ','
|| cursor1.credit_amount
|| ','
|| cursor1.a_number
|| ','
|| cursor1.a__name
|| UTL_TCP.crlf;
END LOOP;
答案 1 :(得分:0)
下面的示例,将查询写入clob,然后写入blob以放入文件
你只需要使用第一步,直到第87行
SELECT dbms_lob.getlength(l_clob)INTO len FROM dual;
DECLARE
l_output utl_file.file_type;
c1 INTEGER DEFAULT dbms_sql.open_cursor;
l_columnvalue VARCHAR2(4000);
l_status INTEGER;
l_colcnt NUMBER := 0;
l_separator VARCHAR2(30);
l_desctbl dbms_sql.desc_tab;
l_flag NUMBER;
l_dir VARCHAR2(50);
l_arq VARCHAR2(100);
l_clob CLOB;
l_query VARCHAR2(50);
vstart NUMBER := 1;
bytelen NUMBER := 32000;
len NUMBER;
my_vr RAW(32000);
x NUMBER;
dest_offset INTEGER;
src_offset INTEGER;
blob_csid NUMBER;
lang_context INTEGER;
blb BLOB;
warning INTEGER;
BEGIN
l_query := 'select * from safx07_v where rownum <=100';
SELECT 'safx07' || to_char(SYSDATE, 'DDMMYY_HH24MISS') || '.txt'
INTO l_arq
FROM dual;
l_dir := 'ORACLE_EXP';
l_output := utl_file.fopen(l_dir, l_arq, 'wb');
--l_output := utl_file.fopen('ORACLE_EXP', 'filename.txt', 'wb', 32760);
--l_separator := separator;
IF l_separator = '' OR l_separator IS NULL THEN
l_separator := chr(9);
END IF;
dbms_sql.parse(c1, l_query, dbms_sql.native);
dbms_sql.describe_columns(c1, l_colcnt, l_desctbl);
dbms_lob.createtemporary(l_clob, TRUE,DBMS_LOB.call);
/*
FOR cr IN (l_query) LOOP
dbms_lob.writeappend(l_clob, length(cr.txt), cr.txt);
END LOOP;*/
FOR i IN 1 .. l_colcnt LOOP
dbms_output.put_line(l_desctbl(i).col_name || l_separator);
dbms_output.put_line(length(l_desctbl(i).col_name || l_separator));
/* utl_file.put(l_output, l_desctbl(i).col_name || l_separator);
dbms_sql.define_column(c1, i, l_columnvalue, 4000);*/
dbms_lob.writeappend(l_clob,
length(l_desctbl(i).col_name || l_separator),
l_desctbl(i).col_name || l_separator);
dbms_sql.define_column(c1, i, l_columnvalue, 4000);
END LOOP;
--utl_file.new_line(l_output);
l_status := dbms_sql.execute(c1);
dbms_lob.writeappend(l_clob, length(chr(10)), chr(10));
WHILE (dbms_sql.fetch_rows(c1) > 0) LOOP
FOR i IN 1 .. l_colcnt LOOP
/* dbms_sql.column_value(c1, i, l_columnvalue);
utl_file.put(l_output, l_columnvalue || l_separator);*/
dbms_sql.column_value(c1, i, l_columnvalue);
dbms_lob.writeappend(l_clob, length(l_columnvalue || l_separator),
l_columnvalue || l_separator);
END LOOP;
dbms_lob.writeappend(l_clob, length(chr(10)), chr(10));
END LOOP;
--utl_file.fclose(l_output);
SELECT dbms_lob.getlength(l_clob) INTO len FROM dual;
dbms_lob.createtemporary(blb, FALSE);
dest_offset := 1;
src_offset := 1;
lang_context := 0;
-- convert to a BLOB here:
dbms_lob.converttoblob(blb, l_clob, dbms_lob.getlength(l_clob),
dest_offset, src_offset, 0, lang_context, warning);
-- if small enough for a single write
IF len < 32760 THEN
utl_file.put_raw(l_output, blb);
utl_file.fflush(l_output);
ELSE
-- write in pieces
vstart := 1;
WHILE vstart < len AND bytelen > 0 LOOP
dbms_lob.read(blb, bytelen, vstart, my_vr);
utl_file.put_raw(l_output, my_vr);
utl_file.fflush(l_output);
-- set the start position for the next cut
vstart := vstart + bytelen;
-- set the end position if less than 32000 bytes
x := x - bytelen;
IF x < 32000 THEN
bytelen := x;
END IF;
END LOOP;
END IF;
dbms_sql.close_cursor(c1);
utl_file.fclose(l_output);
EXCEPTION
WHEN OTHERS THEN
dbms_sql.close_cursor(c1);
utl_file.fclose(l_output);
RAISE;
END;