Процедура Oracle не позволяет записать заголовки в файл csv

#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 в файл на сервере базы данных