Нужна помощь, чтобы получить файл целиком в одном письме размером 4 МБ в Oracle PL/SQL.

Приведенный ниже код в процедуре PL/SQL проверяет размер байта, и если он превышает 30 000 байт, он перебирает данные и отправляет почтовые вложения (файл txt через несколько писем) для каждых 30 000 байтов (30 КБ).
Мне нужно получить файл целиком в одном письме размером 4 МБ в оракуле PL/SQL.

Тип данных lv_message_tab — varchar2(32767) . Могу ли я использовать тип данных CLOB вместо *Varchar2(32767),*если да, предложите, как это сделать.

Заранее миллион спасибо!!!

FOR lv_idx in 1..pv_message.COUNT
      LOOP
         lv_message := lv_message||pv_message(lv_idx)|| lv_cr;

         IF LENGTH(lv_message) >= 30000
         THEN

          lv_message_tab.EXTEND;
          lv_message_tab(lv_message_tab.LAST) := lv_message;
          lv_message := null;

         END IF;

      END LOOP;
--This send the attachment for 30000 characters and above
      IF lv_message_tab.COUNT > 0 
      THEN

           FOR lv_idx in 1..lv_message_tab.COUNT
           LOOP

              UTL_SMTP.HELO(lv_conn, lv_smtp_host);
              UTL_SMTP.MAIL(lv_conn, gc_sender);
              UTL_SMTP.RCPT(lv_conn, lv_to_email_ids);
              UTL_SMTP.RCPT(lv_conn, lv_cc_email_ids);

               UTL_SMTP.DATA(lv_conn,
              'Date: '   || TO_CHAR(SYSDATE, gc_dd_month_yyyy_format) || lv_cr ||
              'From: '   || gc_sender || lv_cr ||
              'Subject: '|| lv_subject || lv_cr ||
              'To: '     || lv_to_email_ids || lv_cr ||
              'CC: '     || lv_cc_email_ids || lv_cr ||

              'MIME-Version: 1.0'|| lv_cr ||    -- Use MIME mail standard
              'Content-Type: multipart/mixed;'|| lv_cr ||
              ' boundary="-----SECBOUND"'|| lv_cr ||
                lv_cr ||

              '-------SECBOUND'|| lv_cr ||
              'Content-Type: text/plain;'|| lv_cr ||
              ' name="excel.csv"'|| lv_cr ||
              'Content-Transfer_Encoding: 8bit'|| lv_cr ||
              'Content-Disposition: attachment;'|| lv_cr ||
              ' filename="'||pv_file_name||'"'|| lv_cr ||
              lv_cr ||lv_message_tab(lv_idx)
              || lv_cr ||   -- Content of attachment
              lv_cr ||

               '-------SECBOUND--' );   

          END LOOP;

      END IF;

      --This send the attachment for the rest of the data...for the last few iterations
      IF lv_message IS NOT NULL
      THEN



          UTL_SMTP.HELO(lv_conn, lv_smtp_host);
          UTL_SMTP.MAIL(lv_conn, gc_sender);
          UTL_SMTP.RCPT(lv_conn, lv_to_email_ids);
          UTL_SMTP.RCPT(lv_conn, lv_cc_email_ids);

           UTL_SMTP.DATA(lv_conn,
          'Date: '   || TO_CHAR(SYSDATE, gc_dd_month_yyyy_format) || lv_cr ||
          'From: '   || gc_sender || lv_cr ||
          'Subject: '|| lv_subject || lv_cr ||
          'To: '     || lv_to_email_ids || lv_cr ||
          'CC: '     || lv_cc_email_ids || lv_cr ||

          'MIME-Version: 1.0'|| lv_cr ||    -- Use MIME mail standard
          'Content-Type: multipart/mixed;'|| lv_cr ||
          ' boundary="-----SECBOUND"'|| lv_cr ||
            lv_cr ||

          '-------SECBOUND'|| lv_cr ||
          'Content-Type: text/plain;'|| lv_cr ||
          ' name="excel.csv"'|| lv_cr ||
          'Content-Transfer_Encoding: 8bit'|| lv_cr ||
          'Content-Disposition: attachment;'|| lv_cr ||
          ' filename="'||pv_file_name||'"'|| lv_cr ||
          lv_cr ||lv_message
          || lv_cr ||   -- Content of attachment
          lv_cr ||

           '-------SECBOUND--' );   


     END IF;


     UTL_SMTP.QUIT(lv_conn);


    pv_rtn := TRUE;

ELSE

    pv_rtn := FALSE;

END IF;

Я вызываю процедуру, вводя данные в виде таблицы сбора, например

ПРОЦЕДУРА

SP1_Send_letter_ATTACH_WAL(pv_job_id IN job.job_id%TYPE,
                           pv_status IN job_transaction_details.status_id%TYPE,
                           pv_subject IN VARCHAR2,
                           pv_message IN stringtable,
                           pv_file_name IN VARCHAR2,
                           pv_date_time IN DATE DEFAULT SYSDATE,
                           pv_rtn OUT BOOLEAN); 

Я просто хочу сохранить данные переменной pv_message в переменную lv_message, которая является типом данных clob.

lv_message CLOB;

КАК ХРАНИТЬ lv_message := pv_message (т.е. тип данных коллекции в тип CLOB). Я уже пытался привести тип, используя функцию to_clob(), например lv_message = to_clob(pv_message), но это не сработало.


person user2294897    schedule 18.04.2013    source источник


Ответы (1)


Попробуйте использовать в цикле UTL_SMTP.WRITE_DATA вместо создания всей почты.

Я не могу проверить это, но должно быть что-то вроде этого:

          UTL_SMTP.HELO(lv_conn, lv_smtp_host);
          UTL_SMTP.MAIL(lv_conn, gc_sender);
          UTL_SMTP.RCPT(lv_conn, lv_to_email_ids);
          UTL_SMTP.RCPT(lv_conn, lv_cc_email_ids);

           UTL_SMTP.DATA(lv_conn,
          'Date: '   || TO_CHAR(SYSDATE, gc_dd_month_yyyy_format) || lv_cr ||
          'From: '   || gc_sender || lv_cr ||
          'Subject: '|| lv_subject || lv_cr ||
          'To: '     || lv_to_email_ids || lv_cr ||
          'CC: '     || lv_cc_email_ids || lv_cr ||

          'MIME-Version: 1.0'|| lv_cr ||    -- Use MIME mail standard
          'Content-Type: multipart/mixed;'|| lv_cr ||
          ' boundary="-----SECBOUND"'|| lv_cr ||
            lv_cr ||

          '-------SECBOUND'|| lv_cr ||
          'Content-Type: text/plain;'|| lv_cr ||
          ' name="excel.csv"'|| lv_cr ||
          'Content-Transfer_Encoding: 8bit'|| lv_cr ||
          'Content-Disposition: attachment;'|| lv_cr ||
          ' filename="'||pv_file_name||'"'|| lv_cr ||
          lv_cr;

 -- this is the importent part (other parts were taken from the question and were just moved out of the loop)
      FOR lv_idx in 1..lv_message_tab.COUNT
       LOOP

         UTL_SMTP.WRITE_DATA(lv_conn, lv_message_tab(lv_idx));
       END LOOP;

     UTL_SMTP.WRITE_DATA(lv_conn,lv_cr ||   -- Content of attachment
          lv_cr ||'-------SECBOUND--' );   

Раньше на OTN был пакет под названием DEMO_MAIL, но я не могу его найти...
Если бы вы его нашли, это было бы очень полезно.

person A.B.Cade    schedule 18.04.2013
comment
Формат почты не следует изменять, и поскольку размер переменной, в которой хранятся данные lv_message, равен 32767 (поскольку это максимальный размер типа данных varchar). Я не получаю почту, если изменю тип данных на CLOB. .so есть ли способ получить его с помощью clob - person user2294897; 18.04.2013
comment
Обратите внимание, что в приведенной выше процедуре есть два блока, если данные меньше 30000 байт, они отправляются как одно письмо. - person user2294897; 18.04.2013
comment
@ user2294897, я не уверен, что правильно тебя понял. Все процедуры в UTL_SMTP ограничены длиной 32767. Поэтому, если вы хотите отправить письмо с сообщением большего размера, вы должны выполнить итерацию и использовать utl_smtp.write_data для добавления дополнительных данных. В своем ответе я использовал ваш код, поэтому я остался с lv_message_tab, но, конечно, вы можете поместить все это в блок и использовать DBMS_LOB.SUBSTR для повторения clob - person A.B.Cade; 18.04.2013
comment
Все, что мне нужно, это отправить текстовый файл размером более 4 МБ (очевидно, он будет больше, чем varchar2 (32767), поэтому я использую тип данных clob для lv_message вместо varchar), используя clob в одном письме, не разделяя файлы на много (повторяющийся) - person user2294897; 19.04.2013
comment
@user2294897 user2294897, ОК, затем сохраните содержимое файла в CLOB, добавьте все заголовки и прочее, а затем, когда придет время добавить содержимое CLOB, выполните цикл по фрагментам 32767 (используйте dbms_lob.substr) и добавьте их с помощью utl_smtp.write_data. это создаст почту с одним файлом (любого размера, который вы хотите) - person A.B.Cade; 19.04.2013
comment
Большое спасибо A.B.Cade .. Это очень помогло - person user2294897; 19.04.2013