#oracle #stored-procedures #plsql #smtp
Вопрос:
У меня есть хранимая процедура, которая считывает значения из таблицы и отправляет их в виде CSV-файла. Я хотел, чтобы заголовки CSV — файла были следующими .
«ИДЕНТИФИКАТОР ,ДАТА ВВОДА ,ПЛАТЕЛЬЩИК ,СУММА ,ТИП ,ПОЛУЧАТЕЛЬ-КОД_СОРТИРОВКИ И _БАНК_АККУМ_НО ,ДОПОЛНИТЕЛЬНЫЕ ОТМЕТКИ_, КОММЕНТАРИИ ,НОМЕР УЧЕТНОЙ ЗАПИСИ ,НОМЕР ПОЛИТИКИ ,ДАТА_ОТ_БРАНЧ_УТВЕРЖДЕНИЯ ,ПОДТВЕРЖДЕН_БИ ,ДАТА ОБНОВЛЕНИЯ, ДАТА ОТПРАВКИ ,ДАТА ,ДАТА, ИДЕНТИФИКАТОР ПОЛЬЗОВАТЕЛЯ, СТАТУС»
Процедура считывает данные из таблицы, добавляет заголовок и сохраняет их в переменной clob . данные выглядят так при печати в журнале, прежде чем они будут добавлены в качестве вложения почты .
Но когда он отправляется по почте как вложение, у него нет заголовка, а есть только данные
Вот мой код :
create or replace PROCEDURE EMAIL_DUMP AS
l_clob2 clob;
l_attach_text2 clob;
l_attach_text_h2 clob;
v_From VARCHAR2(280) := 'abc';
v_Recipient VARCHAR2(280) := 'efg';
v_Subject VARCHAR2(280) := ' Details';
v_Mail_Host VARCHAR2(230) := 'internal';
v_Mail_Conn utl_smtp.Connection;
crlf VARCHAR2 (32767) := chr(13)||chr(10);
c_mime_boundary CONSTANT VARCHAR2 (256) := '¿AAAAA000956¿';
v_index integer;
v_len integer;
FC_SV_STATUS_DESC VARCHAR2(100) := 'open';
Record_id Number ;
Input_date varchar2(100);
Payer varchar2(100);
Amount varchar2(100);
Trans_Type varchar2(100);
Payee varchar2(100);
Remarks varchar2(500);
Comments varchar2(500);
Acc_no varchar2(100);
Policy_no varchar2(100);
Branch_of date ;
Confirmed varchar2(100);
Sheet_update date;
Mail_update date;
Upload_time date;
Upload_id varchar2(100);
CURSOR c2 IS
select FC_CA_RECORD_ID as Record_id,FC_CA_INPUT_DATE as Input_date,FC_CA_PAYER as Payer,FC_CA_AMOUNT as Amount,FC_CA_TYPE as Trans_Type,FC_CA_PAYEE as Payee,FC_CA_ADD_REMARKS as Remarks,FC_CA_COMMENTS as Comments,FC_CA_ACC_NO as Acc_no,FC_CA_POLICY_NO as Policy_no,FC_CA_BRANCHCONF_DATE as Branch_of,FC_CA_CONFIRMED_BY as Confirmed,FC_CA_SHEETUPDATE_DATE as Sheet_update,FC_CA_MAILUPDATE_DATE as Mail_update,FC_CA_UPLOAD_TIME as Upload_time,FC_CA_UPLOAD_ID as Upload_id into Record_id,Input_date,Payer,Amount,Trans_Type,Payee,Remarks,Comments,Acc_no,Policy_no,Branch_of,Confirmed,Sheet_update,Mail_update,Upload_time,Upload_id FROM abc where FC_CA_STATUS =3 ;
BEGIN
l_attach_text_h2 :=
'ID ,INPUT_DATE ,PAYER ,AMOUNT ,TYPE ,PAYEE-SORTCODE_amp;_BANK_ACCOUNT_NO ,ADDITIONAL_REMARKS ,COMMENTS ,ACCOUNT_NUMBER ,POLICY_NUMBER ,DATE_OF_BRANCH_CONFIRMATION ,CONFIRMED_BY ,SHEETUPDATE_DATE ,MAILUPDATE_DATE ,DATE-TIME ,USER_ID ,STATUS ';
FOR employee_rec2 in c2
LOOP
l_attach_text2 := '"' ||
employee_rec2.Record_id || '","' ||
employee_rec2.Input_date || '","' ||
employee_rec2.Payer || '","' ||
employee_rec2.Amount || '","' ||
employee_rec2.Trans_Type || '","' ||
employee_rec2.Payee || '","' ||
employee_rec2.Remarks || '","' ||
employee_rec2.Comments || '","' ||
employee_rec2.Acc_no || '","' ||
employee_rec2.Policy_no || '","' ||
employee_rec2.Branch_of || '","' ||
employee_rec2.Confirmed || '","' ||
employee_rec2.Sheet_update || '","' ||
employee_rec2.Mail_update || '","' ||
employee_rec2.Upload_time || '","' ||
employee_rec2.Upload_id || '","' ||
FC_SV_STATUS_DESC || '"' ||chr(13);
l_clob2 := l_clob2||chr(10)||l_attach_text2;
END LOOP;
l_clob2 := l_attach_text_h2 ||chr(13)|| l_clob2;
DBMS_OUTPUT.put_line(l_clob2);
v_Mail_Conn := utl_smtp.Open_Connection(v_Mail_Host, 25);
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.OPEN_DATA(v_Mail_Conn);
UTL_SMTP.write_data(v_Mail_Conn, 'From: ' || v_From || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'To: ' || v_Recipient || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Subject: ' || REPLACE(v_Subject, '[DATE]',TO_CHAR(sysdate,'DD.MM.YYYY')) || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'MIME-Version: 1.0' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: multipart/mixed; boundary="' || c_mime_boundary || '"' || UTL_TCP.crlf);
-- Mail body:
UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: text/plain' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, ' Details' || UTL_TCP.crlf);
-- Set up attachment header
UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: text/plain' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Content-Disposition: attachment; filename="' || 'myfile.csv' || '"' || UTL_TCP.crlf);
-- Write attachment contents
v_len := DBMS_LOB.getlength(l_clob2);
v_index := 1;
WHILE v_index <= v_len
LOOP
UTL_SMTP.write_data(v_Mail_Conn, DBMS_LOB.SUBSTR(l_clob2, 32000, v_index));
v_index := v_index 32000;
END LOOP;
-- End attachment
UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || '--' || UTL_TCP.crlf);
utl_smtp.CLOSE_DATA(v_mail_conn);
utl_smtp.Quit(v_mail_conn);
DBMS_OUTPUT.put_line('mail send completed...');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line ( 'Error raised: '|| DBMS_UTILITY.FORMAT_ERROR_BACKTRACE || ' - '||sqlerrm);
system.intranet_utils.INTRANET_LOG_ERRORS('procedure EmailDump',
system.intranet_utils.INTRANET_GET_ERRMSG, 'Error in EmailDump');
END EMAIL_DUMP;
Если я отредактирую часть вложения почты ,как показано ниже , я смогу получить правильный CSV-файл в качестве вложения с прослушивающим устройством и данными, но затем я не смогу добавить текстовое сообщение в почту.
UTL_SMTP.write_data(v_Mail_Conn, 'From: ' || v_From || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'To: ' || v_Recipient || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Subject: ' || REPLACE(v_Subject, '[DATE]',TO_CHAR(sysdate,'DD.MM.YYYY')) || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'MIME-Version: 1.0' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: multipart/mixed; boundary="' || c_mime_boundary || '"' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'This is a multi-part message in MIME format.' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, 'Content-Type: text/plain' || UTL_TCP.crlf);
-- Set up attachment header
UTL_SMTP.write_data(v_Mail_Conn, 'Content-Disposition: attachment; filename="' || 'CMTL.csv' || '"' || UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf);
-- Write attachment contents
v_len := DBMS_LOB.getlength(l_clob2);
v_index := 1;
WHILE v_index <= v_len
LOOP
UTL_SMTP.write_data(v_Mail_Conn, DBMS_LOB.SUBSTR(l_clob2, 32000, v_index));
v_index := v_index 32000;
END LOOP;
-- End attachment
UTL_SMTP.write_data(v_Mail_Conn, UTL_TCP.crlf);
UTL_SMTP.write_data(v_Mail_Conn, '--' || c_mime_boundary || '--' || UTL_TCP.crlf);
Может ли кто-нибудь сказать мне, почему я не могу отправить письмо как с телом письма, так и с вложением ?
Комментарии:
1. Поскольку БД никогда не записывает заголовки, это зависит от того, какой клиент вы используете. Если ваша процедура действует как собственный клиент , то она записывает триггеры.
2. если заголовок находится в clob перед записью в csv-файл, то, возможно, у вас проблема на стороне клиента. Вы пробовали прочитать csv-файл на сервере ?
3. @RobertoHernandez Я напечатал clob перед utl_smtp.запись …. в clob есть заголовки данные . Вы можете видеть это на первом изображении в вопросе….. Есть ли способ, которым я могу записать весь clob в виде содержимого csv-файла …. Я чувствую, что некоторые из строк заголовков, которые являются первой строкой clob, пропускаются
4. @Страхующий в блоке уже есть заголовки и данные … как вы можете видеть на первом изображении, которым я поделился … кое-как, когда я пишу блок в качестве вложения … строка заголовков (первая строка ) пропускается …. Я не понимаю, почему он не пишет весь комок
5. @TJ32, если у вас есть каталог базы данных с правами пользователя, которому принадлежит процедура, вы можете использовать
DBMS_XSLPROCESSOR.clob2file
для записи clob в файл на сервере базы данных