powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Передача письма с вложением. Готовое решение
25 сообщений из 274, страница 4 из 11
Передача письма с вложением. Готовое решение
    #37264576
_Ildar_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Ildar_,

Есть вопрос. Если используется Exchange 2010, а он требует авторизации, то как это сделать с помощью вышеуказанного пакета?

Спасибо!
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37266493
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Ildar__Ildar_,

Есть вопрос. Если используется Exchange 2010, а он требует авторизации, то как это сделать с помощью вышеуказанного пакета?

Спасибо!

С exchange не работал, но по идее если авторизация smtp должно работать:
Код: plaintext
1.
2.
3.
4.
 BEGIN
	 MAIL_PKG.SET_MAILSERVER ('localhost', 25 );
	 MAIL_PKG.SET_AUTH ('e.petrov','password');
        MAIL_PKG.SEND( 'a.ivanov@yourcomany.ru','Test subject', 'Some message!');
  END;
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37612568
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chameleon82Всем спасибо за подсказки.
Я в свою очередь обновил пакет, добавил возможность вставлять блобы (из базы или сформированные вручную).
Выкладываю обновленную версию целиком:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
...
 PROCEDURE SEND ( mailto IN VARCHAR2
				, subject IN VARCHAR2
				, message IN VARCHAR2
                , mailfrom IN VARCHAR2 DEFAULT NULL
				, mimetype IN VARCHAR2 DEFAULT 'text/plain'
				, priority IN NUMBER DEFAULT NULL
                )
 IS
...
   amt CONSTANT BINARY_INTEGER := 48; -- 48bytes binary convert to 128bytes of base64.
...
 BEGIN

...	
	--Attachments
	IF MAIL_PKG.attachments.count>0 THEN
	  FOR x IN 1 .. MAIL_PKG.attachments.count LOOP
   ...
             ps:=1; v_amt:=amt;
		     LOOP
		       BEGIN
		         dbms_lob.read (vFile, v_amt, ps, vRAW);
			     ps := ps + v_amt;
                 utl_smtp.write_raw_data(v_Mail_Conn, UTL_ENCODE.base64_encode(vRAW));


изменение параметра amt с 48 до, например, 960, повышает скорость отправки писем с вложениями раз в 10..20.
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37810424
bgrena
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chameleon82.. свою очередь обновил пакет, добавил возможность вставлять блобы (из базы или сформированные вручную).
Выкладываю обновленную версию целиком:

Спасибо за превосходный пакет. Получил удовольствие. Мне не хватает только переходника
от внешних файлов (OS) к блобам
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37810970
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bgrenaСпасибо за превосходный пакет. Получил удовольствие. Мне не хватает только переходника
от внешних файлов (OS) к блобам

Спасибо. А разве этого не достаточно?
Код: plsql
1.
2.
3.
4.
5.
 -- Add attachment from file 
	 MAIL_PKG.ADD_ATTACHMENT( 'MYFILEDIR'
							 ,'myfile.jpeg'
							 ,'image/jpeg'
							);



Создать директорию просто:
Код: plsql
1.
CREATE DIRECTORY MYFILEDIR AS "c:\tempfiles\";



Если шаблоны писем храните в файлах, запихать их в блоб тоже несложно:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
DECLARE
  src_lob  BFILE := BFILENAME('MYFILEDIR', '/tmp/mail.tpl');
  dest_lob BLOB;
BEGIN
  DBMS_LOB.OPEN(src_lob, DBMS_LOB.LOB_READONLY);
  DBMS_LOB.LoadFromFile( DEST_LOB => dest_lob,
                         SRC_LOB  => src_lob,
                         AMOUNT   => DBMS_LOB.GETLENGTH(src_lob) );
  DBMS_LOB.CLOSE(src_lob);
END;
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37811053
sinitsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chameleon82,

спасибо, мне тоже актуально, почерпну из Вашего опыта :)
переделаю только под utl_tcp от utl_smtp уже мало что осталось.

от себя могу сказать, есть у нас похожее решение на перле ( не для базы ),
теги тоже "руками" проставляются, иногда письма режут фильтры безопасников,
происходит потому, что теги "нестандартные",
т.е. они соответствуют rfc, но фильтры заточены под outlook.
т.е. в письмо надо вставлять не нужные теги чтобы оно было похоже
на outlook'овское, во всяком случае у нас тут.
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37811095
Фотография Ден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот уже готовый пример на java, гдето скачал, отлично работает
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37811101
Фотография Ден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37811106
Фотография Ден
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37881828
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
заменили
Код: plsql
1.
    utl_smtp.write_data(v_Mail_Conn, 'Date: ' || TO_CHAR(SYSDATE,     'Dy, DD Mon YYYY hh24:mi:ss',       'NLS_DATE_LANGUAGE = ''american''') || crlf);


на
Код: plsql
1.
    utl_smtp.write_data(v_Mail_Conn, 'Date: ' || TO_CHAR(SYSTIMESTAMP,'Dy, DD Mon YYYY HH24:MI:SS TZHTZM','NLS_DATE_LANGUAGE = ''american''') || crlf);

тайм-зону добавили
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37925856
Bodyaya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Есть решение для отправки вложений (BLOB) больше 32к. В курсоре у меня перебираются вложения (их может быть много в одном письме и какждое из них может быть любого размера). В моем случае тестировал на JPEG до 1,6 Мб - больше стало лень:)

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
procedure do_email_files(from_name varchar2,
                      to_names varchar2,
                      subject varchar2,
                      clob_html_message clob,
                      b_id_email_body number)
is

   smtp_host          varchar2(256) := '*****';
   smtp_port          number := 25;

   boundary           constant varchar2(256) := 'CES.Boundary.DACA587499938898';

   recipients         varchar2(32767);
   directory_path     varchar2(256);
   file_path          varchar2(256);
   mime_type          varchar2(256);
   file_name          varchar2(256);
   cr                 varchar2(1) := chr(13);
   lf                 varchar2(1) := chr(10);
   crlf               varchar2(2) := cr || lf;
   mesg               varchar2(32767);
   conn               UTL_SMTP.CONNECTION;
   i                  binary_integer;
   my_code            number;
   my_errm            varchar2(32767
Begin

..........

     for i in (select * from email_att e where e.id_email_body = b_id_email_body) loop

         if i.attachment is null then
            exit;
         end if;
         if mime_type is null then
            mime_type := 'text/plain';
         end if;

         mesg := crlf || '--' || boundary || crlf;
         mesg := mesg || 'Content-Type: ' || mime_type ||
            '; name="' || i.att_name || '"' || crlf ||
            'Content-Disposition: attachment; filename="' ||
            i.att_name || '"' || crlf ||
            'Content-Transfer-Encoding: base64' || crlf || crlf ;
         utl_smtp.write_data(conn,mesg);

         append_file(null,i.att_name,mime_type,conn,blob_attach => i.attachment);

      end loop;


   mesg := crlf || '--' || boundary || '--' || crlf;
   utl_smtp.write_data(conn,mesg);


   utl_smtp.close_data(conn);
   utl_smtp.quit(conn);

..................
..................


   PROCEDURE append_file(
      directory_path IN VARCHAR2 default null,
      file_name IN VARCHAR2 default null,
      mime_type IN VARCHAR2,
      conn IN OUT UTL_SMTP.CONNECTION,
      clob_attach IN CLOB default null,
      blob_attach IN BLOB default null) IS

      file_handle     utl_file.file_type;
      bfile_handle    bfile;
      lob_len         number(38) := 0;
      lob_pos         number(38) := 1;
      read_bytes      number(38);
      lf_at           number(38);
      line            varchar2(32767); 
      data            raw(32767);
      my_code         number;
      my_errm         varchar2(32767);

   begin

      begin
   
.........................


         if clob_attach is not null then
            lob_len := dbms_lob.getlength(clob_attach);
         elsif blob_attach is not null then
            lob_len := dbms_lob.getlength(blob_attach);
         end if;
   
 
         loop

            if directory_path is not null and substr(mime_type,1,4) = 'text' then
               utl_file.get_line(file_handle,line);
               utl_smtp.write_data(conn,line || crlf);

            else


               if clob_attach is not null then
                  lf_at := dbms_lob.instr(clob_attach,lf,lob_pos);
                  if lf_at = 0 then
                     lf_at := lob_len + 1;
                  end if;
                  read_bytes := lf_at - lob_pos;
                  if read_bytes > 0
                     and dbms_lob.substr(clob_attach,1,lf_at-1) = cr then
                     read_bytes := read_bytes - 1;
                  end if;
                  if read_bytes > 0 then
                     dbms_lob.read(clob_attach,read_bytes,lob_pos,line);
--                     utl_smtp.write_data(conn,line);
                     utl_smtp.write_raw_data(conn,UTL_RAW.CAST_TO_RAW(line));
                  end if;
                  utl_smtp.write_data(conn,crlf);
                  lob_pos := lf_at + 1;

               else
                  if lob_pos + 57 - 1 > lob_len then
                     read_bytes := lob_len - lob_pos + 1;
                  else
                     read_bytes := 57;
                  end if;
                  if blob_attach is not null then
                     dbms_lob.read(blob_attach,read_bytes,lob_pos,data);
                  else
                     dbms_lob.read(bfile_handle,read_bytes,lob_pos,data);
                  end if;
                  utl_smtp.write_raw_data(conn,utl_encode.base64_encode(data));
                  lob_pos := lob_pos + read_bytes;
               end if;

               if lob_pos > lob_len then
                  exit;
               end if;

            end if;
      
         end loop;

..............................
..............................



Код можно подогнать под свой пакет.
Сам его собирал по кусочкам :)
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37936540
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В пакете уже есть эта возможность (т.е. отправлять неограниченное число файлов over 32kb)
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37952235
seregaLOKI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chameleon82, возникла такая проблема. Есть необходимости передать в mesage текст более 32к символов. Использую CLOB, база имеет настройку NLS_CHARACTERSET CL8MSWIN1251. При конверте русских символов в UTF8 в разделе --Message мы на выходе получаем бред.
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37953686
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Обновил пакет, message теперь clob, поэтому если формировать текст размером больше 32кб без вложений, проблем не должно возникнуть, заодно пофиксил некоторые баги, спасибо andreymx.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
CREATE OR REPLACE PACKAGE MAIL_PKG IS
-- --------------------------------------------------------------------------
-- Name         : MAIL_PKG
-- Author       : Nekrasov Alexander
-- Description  : Mail package, send email with attachments
-- Ammedments   :
--   When         Who         What
--   ===========  ==========  =================================================
--   22-JAN-2010  Nekrasov A.  Initial Creation
--   26-MAY-2010  Nekrasov A.  Update package bugs
--   11-OCT-2010  Nekrasov A.  Add Blob attachments
--   10-SEP-2012  Nekrasov A.  Upd. Message type varchar2>clob
-- --------------------------------------------------------------------------

/* EXAMPLE:

 1) Short text email
    BEGIN
      MAIL_PKG.SEND( 'a.ivanov@yourcomany.ru','Test subject', 'Some message!');
    END;

 2) Send mail with text message over 32kbytes formed with CLOB 
    DECLARE 
      v clob:='Some text message over 32kb'||chr(10)||chr(13);
      t varchar2(255):=' The quick brown fox jumps over the lazy dog. '
                     ||' The quick brown fox jumps over the lazy dog. '
                     ||' The quick brown fox jumps over the lazy dog. '||chr(10)||chr(13);
    BEGIN
      for x in 1..300 loop
        v:=v||to_char(x)||' '||t;
      end loop;
      MAIL_PKG.SEND( 'a.ivanov@yourcompany.ru','Test subject', v);
    END ;  

 3) Send mail with message over 32kbytes formed with BLOB
    DECLARE
      vBlob BLOB;
      BEGIN
     SELECT file_data INTO vBlob FROM FND_LOBS WHERE FILE_ID = 161005;                        
     MAIL_PKG.ADD_ATTACHMENT( vBlob
                             ,'MessageOver32kb.htm'
                             ,'text/html'
                            );                            
      MAIL_PKG.SEND( 'a.ivanov@yourcomany.ru','Big message', NULL);    
    END;
    
 4) Extension Email with attacments
    DECLARE
      vBlob BLOB;
    BEGIN
     MAIL_PKG.SET_MAILSERVER ('localhost',25);
     MAIL_PKG.SET_AUTH ('a.nekrasov','password');

     -- Add attachment from file 
     MAIL_PKG.ADD_ATTACHMENT( 'ODPDIR'
                             ,'girl3d.jpeg'
                             ,'image/jpeg'
                            );

     -- Add attachment from BLOB    
     SELECT file_data INTO vBlob FROM FND_LOBS WHERE FILE_ID = 161005;                        
     MAIL_PKG.ADD_ATTACHMENT( vBlob
                             ,'ReportResult.htm'
                             ,'text/html'
                            );                            

     MAIL_PKG.SEND( mailto => 'A. Ivanov <a.ivanov@yourcomany.ru>;, O.Petrov <o.petrov@yourcompany.ru>;'
                  , subject => 'Test subject'
                  , message => 'Some <b>bold</b> message!'
                  , mailfrom => 'Oracle Notify <no-reply@yourcompany.ru>;'
                  , mimetype => 'text/html'
                  , priority => 1
                  );
    END;
*/

 POP3 CONSTANT VARCHAR2(4):='POP3';
 SMTP CONSTANT VARCHAR2(4):='SMTP';
 IMAP CONSTANT VARCHAR2(4):='IMAP';

 DEBUG BOOLEAN := FALSE;

 -- SET_MAILSERVER:
 --  Set up mail server for send emails. Default Localhost
 -- IN
 -- MAILSERVER is ip or url of mail server
 -- MAILPORT is port for mail server. Default 25
 PROCEDURE SET_MAILSERVER ( mailserver varchar2
                          , mailport number default 25
                          );

 -- SET_AUTH
 --  Set authorization on smtp server
 -- IN
 -- AUTH_USER is authorization user
 -- AUTH_PASS is password for AUTH_USER
 --
 -- Execute SET_AUTH(); -- for disable authorization
 PROCEDURE SET_AUTH (  auth_user varchar2 default null
                     , auth_pass varchar2 default null
                          );

 -- ENCODE:
 --  Encodes string to email compatible view
 -- IN
 -- STR is string to convert
 -- TP is type of convert:
 --    B - is base64 encoding
 FUNCTION ENCODE( str IN VARCHAR2
                , tp IN VARCHAR2 DEFAULT 'Q') RETURN VARCHAR2;

 -- PREPARE
 --  Prepare configs for email.
 PROCEDURE PREPARE;

 -- ADD_RCPT
 --  Add recipient to recipients list exploded by  ','
 -- STR is variable with recipients
 -- RCPTMAIL is recipient mail added to STR
 -- RCPTNAME is recipient name added to STR
 -- Example: str='user1@domain.ru' rcptmail='user2@domain.ru'
 --  after => str='user1@domain.ru, user2@domain.ru'
 PROCEDURE ADD_RCPT( str IN OUT VARCHAR2
                   , rcptmail IN VARCHAR2
                   , rcptname IN VARCHAR2 DEFAULT NULL);

 -- ADD_ATTACHMENT
 --  Add file-attachment to attachments list to email
 -- IN
 -- DIRNAME is logical link to access physical directories of server. See DBA_DIRECTORIES table
 -- FILENAME is name of file to attach
 -- MIMETYPE is mime-type for sended file
 -- NAME is name for attached file for email. Default eq FILENAME
 PROCEDURE ADD_ATTACHMENT ( dirname IN varchar2
                          , filename IN varchar2
                          , mimetype IN varchar2 DEFAULT 'text/plain'
                          , name IN varchar2 DEFAULT NULL
                           );
 -- ADD_ATTACHMENT
 --  Add blob-attachment to attachments list to email
 -- IN
 -- BLOBLOC - Blob locator for attached blob
 -- FILENAME is name of file to attach
 -- MIMETYPE is mime-type for sended file
 PROCEDURE ADD_ATTACHMENT ( blobloc IN blob
                          , filename IN varchar2
                          , mimetype IN varchar2 DEFAULT 'text/html'
                           );
                           
 -- SEND
 --  Send email with attachments to recipient
 -- IN
 -- MAILTO is name and email addresses of recipients ( ex. "user@domain.com"
 --       , "User Name <user@domain.com>;", "User1 <user1@domain>;, User2 <user2@domain>;")
 -- SUBJECT is subject of email
 -- MESSAGE is message of email
 -- MAILFROM is name and email of sender. (ex. "no-reply@domain", "Notify system <no-reply@domain>;")
 -- MIMETYPE is mime-type of message. Available values is 'text/plain' and 'text/html'
 -- PRIORITY is priority of mail (1 - High, 2 - Highest, 3 - Normal, 4 - Lowest, 5 - Low)
 PROCEDURE SEND ( mailto IN VARCHAR2
                , subject IN VARCHAR2
                , message IN CLOB
                , mailfrom IN VARCHAR2 DEFAULT NULL
                , mimetype IN VARCHAR2 DEFAULT 'text/plain'
                , priority IN NUMBER DEFAULT NULL
                );

END MAIL_PKG;
/

CREATE OR REPLACE PACKAGE BODY MAIL_PKG
IS

 mailserver VARCHAR2(30):='localhost';
 mailport INTEGER:=25;
 auth_user VARCHAR2(50);
 auth_pass VARCHAR2(50);
 crlf         VARCHAR2(2)  := utl_tcp.CRLF; -- chr(13)||chr(10);

 type attach_row is record ( dirname varchar2(30)
                           , filename  varchar2(30)
                           , name  varchar2(30)
                           , mimetype varchar2(30)
                           , blobloc blob
                           , attachtype varchar2(30)
                           );
 type attach_list is table of attach_row;
 attachments attach_list;

 type rcpt_row is record ( rcptname varchar2(100)
                     , rcptmail varchar2(50)
                     );
 type rcpt_list is table of rcpt_row;

 PROCEDURE SET_MAILSERVER ( mailserver varchar2
                          , mailport number default 25
                          ) IS
 BEGIN
  MAIL_PKG.mailserver := mailserver;
  MAIL_PKG.mailport := mailport;
 END;

 PROCEDURE SET_AUTH (  auth_user varchar2 default null
                     , auth_pass varchar2 default null
                          ) IS
 BEGIN
   MAIL_PKG.auth_user := auth_user;
   MAIL_PKG.auth_pass := auth_pass;
 END;

 FUNCTION ENCODE(str IN VARCHAR2, tp IN VARCHAR2 DEFAULT 'Q') RETURN VARCHAR2 IS
 BEGIN
   -- ToDo: UTL_ENCODE.QUOTED_PRINTABLE | UTL_ENCODE.BASE64
   IF tp='B' THEN
     RETURN '=?utf-8?b?'|| UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw (CONVERT (SUBSTR(str,1,24), 'UTF8'))))|| '?='
         || CASE WHEN SUBSTR(str,25) IS NOT NULL THEN crlf || ' '|| ENCODE(SUBSTR(str,25),tp) END;
   ELSIF tp='Q' THEN
     RETURN '=?utf-8?q?' || UTL_RAW.cast_to_varchar2(utl_encode.QUOTED_PRINTABLE_ENCODE(utl_raw.cast_to_raw(CONVERT (SUBSTR(str,1,8), 'UTF8') ))) || '?='
         || CASE WHEN SUBSTR(str,9) IS NOT NULL THEN crlf || ' '|| ENCODE(SUBSTR(str,9),tp) END;
   ELSE
     RETURN str;
   END IF;
 END;

 PROCEDURE PREPARE
 IS
 BEGIN
   MAIL_PKG.attachments:=MAIL_PKG.attach_list();
 END;

 PROCEDURE ADD_RCPT( str IN OUT VARCHAR2
                   , rcptmail IN VARCHAR2
                   , rcptname IN VARCHAR2 DEFAULT NULL) IS
  rcpt varchar2(255);
 BEGIN
  rcpt:=CASE WHEN rcptname is null THEN
          rcptmail
        ELSE
          trim(replace(replace(rcptname,',',' '),';',' '))||' <'|| rcptmail ||'>'
        END;
  IF trim(str) is NULL THEN
     str :=  trim(rcpt);
  ELSE
     str := str||', '||trim(rcpt);
  END IF;
 END;

 PROCEDURE ADD_ATTACHMENT ( dirname IN varchar2
                          , filename IN varchar2
                          , mimetype IN varchar2 DEFAULT 'text/plain'
                          , name IN varchar2 DEFAULT NULL
                           )
 IS
  v_fl BFILE :=BFILENAME(dirname,filename);
 BEGIN
   IF DBMS_LOB.FILEEXISTS (v_fl)=1 THEN
      MAIL_PKG.attachments.extend;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).dirname:=dirname;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).filename:=filename;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).name:=nvl(name,filename);
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).mimetype:=mimetype;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).attachtype:='FILE';      
   ELSE
      RAISE_APPLICATION_ERROR(-20001, 'File is not exists');
   END IF;
 END;
 
 PROCEDURE ADD_ATTACHMENT ( blobloc IN blob
                          , filename IN varchar2
                          , mimetype IN varchar2 DEFAULT 'text/html'
                           )
 IS 
 BEGIN
      MAIL_PKG.attachments.extend;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).name:=filename;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).mimetype:=mimetype;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).blobloc:=blobloc;      
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).attachtype:='BLOB';      
 END;                            
 

 FUNCTION CREATE_RCPT_LIST(mailto IN VARCHAR2) RETURN MAIL_PKG.rcpt_list IS
  v_mailto VARCHAR2(4096) := replace(mailto,';',',')||',';
  pntr INTEGER;
  buf VARCHAR2(255);
  rcptmail VARCHAR2(255);
  rcptlist MAIL_PKG.rcpt_list:=MAIL_PKG.rcpt_list();
 BEGIN
  FOR maxrcptnts IN 1..50
  LOOP
     pntr:=INSTR(v_mailto,','); buf := substr(v_mailto,1,pntr-1);
     IF pntr>0 THEN
       IF INSTR(buf,'<')>0 AND INSTR(buf,'>')>0 THEN
         rcptmail:= SUBSTR(buf,INSTR(buf,'<')+1,INSTR(SUBSTR(buf,INSTR(buf,'<')+1),'>')-1);
         IF rcptmail IS NOT NULL THEN
            rcptlist.extend;
            rcptlist(rcptlist.count).rcptmail := TRIM(rcptmail);
            rcptlist(rcptlist.count).rcptname := TRIM(SUBSTR(buf,1,INSTR(buf,'<')-1));
         END IF;
       ELSE
         rcptmail := TRIM(buf);
         IF rcptmail IS NOT NULL THEN
           rcptlist.extend;
           rcptlist(rcptlist.count).rcptmail:= TRIM(rcptmail);
         END IF;
       END IF;
     ELSE
       EXIT;
     END IF;
     v_mailto := substr(v_mailto,pntr+1);
   END LOOP;
   RETURN rcptlist;
 END;

 PROCEDURE SEND ( mailto IN VARCHAR2
                , subject IN VARCHAR2
                , message IN CLOB
                , mailfrom IN VARCHAR2 DEFAULT NULL
                , mimetype IN VARCHAR2 DEFAULT 'text/plain'
                , priority IN NUMBER DEFAULT NULL
                )
 IS
   v_Mail_Conn  utl_smtp.Connection;
   boundary VARCHAR2(50) := '-----7D81B75CCC90DFRW4F7A1CBD';
   vFile BFILE;
   vRAW RAW(32767);
   amt CONSTANT BINARY_INTEGER := 10368; -- 48bytes binary convert to 128bytes of base64. (32767/2 max for raw convert)
   v_amt BINARY_INTEGER;
   ps BINARY_INTEGER := 1;
   message_part varchar2(32767);
   v_mime VARCHAR2(30);
   reply UTL_SMTP.REPLY;
   replies UTL_SMTP.REPLIES;
   rcptlist MAIL_PKG.rcpt_list;
   sndr MAIL_PKG.rcpt_row;
 BEGIN
    rcptlist:=create_rcpt_list(mailto);
    IF rcptlist.count=0 THEN
      RAISE_APPLICATION_ERROR(-20001, 'Recipients requered');
    END IF;
    IF mimetype<>'text/html' and mimetype<>'text/plain' THEN
      RAISE_APPLICATION_ERROR(-20001, 'MimeType must be "text/html" or "text/plain"');
    ELSE
      v_mime:=mimetype;
    END IF;
    v_Mail_Conn := utl_smtp.Open_Connection(MAIL_PKG.mailserver, MAIL_PKG.mailport);
    replies:=utl_smtp.Ehlo(v_Mail_Conn,MAIL_PKG.mailserver);
    if create_rcpt_list(mailfrom).count>0 then
      sndr := create_rcpt_list(mailfrom)(1);
    else
      sndr := create_rcpt_list( 'mail@' || UTL_INADDR.GET_HOST_NAME )(1); -- host from oracle-server
      -- sndr := create_rcpt_list( 'mail@' || substr(replies(1).text,1,instr(replies(1).text,' ')-1))(1); -- Addr from ehlo answer
    end if;

    if mail_pkg.auth_user is not null then
       for x IN 1 .. replies.count loop
          IF INSTR(replies(x).text,'AUTH')>0 then -- If server supply authorization
            utl_smtp.command(v_Mail_Conn, 'AUTH LOGIN');
            utl_smtp.command(v_Mail_Conn,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(auth_user))));
            utl_smtp.command(v_Mail_Conn,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(auth_pass))));
            exit;
         END IF;
       end loop;
    end if;

    utl_smtp.Mail(v_Mail_Conn, sndr.rcptmail);
    FOR rcpts IN 1 .. rcptlist.count
    LOOP
      utl_smtp.Rcpt(v_Mail_Conn, rcptlist(rcpts).rcptmail);
    END LOOP;

    utl_smtp.open_data(v_Mail_Conn); -- open data sheet
    utl_smtp.write_data(v_Mail_Conn, 'Date: ' || TO_CHAR(SYSTIMESTAMP,'Dy, DD Mon YYYY HH24:MI:SS TZHTZM','NLS_DATE_LANGUAGE = ''american''') || crlf);
    utl_smtp.write_data(v_Mail_Conn, 'From: ');
    if sndr.rcptname is not null then
        utl_smtp.write_data(v_Mail_Conn, MAIL_PKG.ENCODE(sndr.rcptname) ||' <'|| sndr.rcptmail || '>');
    else
        utl_smtp.write_data(v_Mail_Conn, sndr.rcptmail);
    end if;
    utl_smtp.write_data(v_Mail_Conn, crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Subject: '|| MAIL_PKG.ENCODE(subject) || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'To: ');
    FOR rcpts IN 1 .. rcptlist.count
    LOOP
      if rcpts>1 then
       utl_smtp.write_data(v_Mail_Conn, ',');
      end if;
      if rcptlist(rcpts).rcptname is not null then
        utl_smtp.write_data(v_Mail_Conn, MAIL_PKG.ENCODE(rcptlist(rcpts).rcptname) ||' <'|| rcptlist(rcpts).rcptmail || '>');
      else
        utl_smtp.write_data(v_Mail_Conn, rcptlist(rcpts).rcptmail);
      end if;
    END LOOP;
    utl_smtp.write_data(v_Mail_Conn, crlf );

    IF priority IS NOT NULL and priority BETWEEN 1 AND 5 THEN
      utl_smtp.write_data(v_Mail_Conn, 'X-Priority: ' || priority || crlf );
    END IF;
    utl_smtp.write_data(v_Mail_Conn, 'MIME-version: 1.0' || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Type: multipart/mixed;'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, ' boundary="'||boundary||'"'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );
 
    --Message
    IF message IS NOT NULL THEN    
    utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||v_mime||'; charset="utf-8"'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Transfer-Encoding: 8bit'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );
    -- utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(CONVERT(message,'UTF8')));
    ps:=1; v_amt:=amt;
    LOOP
      BEGIN
        dbms_lob.read(message, v_amt, ps, message_part);
        ps := ps + v_amt;
        utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(CONVERT(message_part,'UTF8')));                 
      EXCEPTION
        WHEN no_data_found THEN
             EXIT;
      END;            
    END LOOP; 
    utl_smtp.write_data(v_Mail_Conn, crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );
    END IF;
    
    --Attachments
    IF MAIL_PKG.attachments.count>0 THEN
      FOR x IN 1 .. MAIL_PKG.attachments.count LOOP
          utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
          -- HOTFIX
          IF message IS NOT NULL OR x!=1 THEN
            utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||MAIL_PKG.attachments(x).mimetype||';'|| crlf );
            utl_smtp.write_data(v_Mail_Conn, ' name="');
            utl_smtp.write_raw_data(v_Mail_Conn,utl_raw.cast_to_raw(MAIL_PKG.attachments(x).name));
            utl_smtp.write_data(v_Mail_Conn, '"' || crlf);
            utl_smtp.write_data(v_Mail_Conn, 'Content-Transfer-Encoding: base64'|| crlf );
            utl_smtp.write_data(v_Mail_Conn, 'Content-Disposition: attachment;'|| crlf );
            utl_smtp.write_data(v_Mail_Conn, ' filename="' || MAIL_PKG.ENCODE(MAIL_PKG.attachments(x).name) || '"' || crlf);
          ELSE
           utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||MAIL_PKG.attachments(x).mimetype||'; charset="utf-8"'|| crlf );
           utl_smtp.write_data(v_Mail_Conn, 'Content-Transfer-Encoding: base64'|| crlf );
          END IF;            
          utl_smtp.write_data(v_Mail_Conn, crlf );
          IF MAIL_PKG.attachments(x).attachtype = 'FILE' THEN 
             vFile := BFILENAME(MAIL_PKG.attachments(x).dirname,MAIL_PKG.attachments(x).filename);
             dbms_lob.fileopen(vFile, dbms_lob.file_readonly);
             ps:=1; v_amt:=amt;
             LOOP
               BEGIN
                 dbms_lob.read (vFile, v_amt, ps, vRAW);
                 ps := ps + v_amt;
                 utl_smtp.write_raw_data(v_Mail_Conn, UTL_ENCODE.base64_encode(vRAW));
               EXCEPTION
                 WHEN no_data_found THEN
                   EXIT;
               END;            
             END LOOP;
             dbms_lob.fileclose(vFile);
          ELSIF MAIL_PKG.attachments(x).attachtype = 'BLOB' THEN
               dbms_lob.open(MAIL_PKG.attachments(x).blobloc, dbms_lob.file_readonly);
             ps:=1; v_amt:=amt;
             LOOP
               BEGIN
                 dbms_lob.read (MAIL_PKG.attachments(x).blobloc, v_amt, ps, vRAW);
                 ps := ps + v_amt;
                 utl_smtp.write_raw_data(v_Mail_Conn, UTL_ENCODE.base64_encode(vRAW));
               EXCEPTION
                 WHEN no_data_found THEN
                   EXIT;
               END;            
             END LOOP;
             dbms_lob.close(MAIL_PKG.attachments(x).blobloc);                           
          END IF;                   

          utl_smtp.write_data(v_Mail_Conn, crlf );
          utl_smtp.write_data(v_Mail_Conn, crlf );
      END LOOP;
    END IF;

    -- Final Boundary
    utl_smtp.write_data(v_Mail_Conn, '--' || boundary || '--');

    utl_smtp.close_data(v_Mail_Conn);
    utl_smtp.quit(v_Mail_Conn);

    -- Clear attachments
    MAIL_PKG.attachments:=MAIL_PKG.attach_list();

 EXCEPTION
    WHEN OTHERS THEN
       BEGIN
         MAIL_PKG.attachments:=MAIL_PKG.attach_list();
         utl_smtp.rset(v_Mail_Conn);
         utl_smtp.quit(v_Mail_Conn);
       EXCEPTION WHEN OTHERS THEN NULL;
       END;
    RAISE;
 END;


 
BEGIN
  MAIL_PKG.attachments:=MAIL_PKG.attach_list();
END;
/
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37953704
seregaLOKI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
chameleon82,

Огромное спасибо!
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37960268
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Итак, теперь я научил пакет не только отправлять почту, но и принимать ее. Пока еще все достаточно сыровато, но для тех, кто хочет побаловаться, можете поиграться.
Итак, что может пакет:
- Получить список писем во встроенный массив, получить их заголовки (поля "от","кому","тема","дата" для удобства продублированы во встроенные переменные).
- Получить тело сообщения
- Получить вложения! (все вложения представлены как CLOB)
- Распознать у вложения имя файла (впрочем, все заголовки вложения сохраняются в массив)
- Текст вложений декодируется в соответствии с методом и кодовой страницей (не все кодовые страницы проверял) и его можно сразу преобразовывать в BLOB для сохранения или как есть сохранять в базу

Замеченные косяки:
- Письма объемом более 1Мб умирают при получении. Как я понимаю, связано с необходимостью конкатенации CLOB и мелких строк (по 72 байта) до нужного объема. Как победить пока не знаю.
- Пока некорректно определяются вложения (бывают пустые вложения без содержимого. связано с декодировкой boundares, разберусь позже, если кому-то будет необходимо)
- Могут встретиться другие косяки по декодировке текста сообщения и т.п. Для самостоятельной отладки добавил фунцию PDEBUG.

Пример работы с получением почты:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
 BEGIN
       MAIL_PKG.DEBUG := TRUE;
       MAIL_PKG.DEBUG_LEVEL := MAIL_PKG.DEBUG_WARNINGS;
       MAIL_PKG.SET_MAILSERVER ('yourmailserver.com');
       MAIL_PKG.SET_AUTH ('a.ivanov','mypass');
       MAIL_PKG.MAIL_CONNECT;
       DBMS_OUTPUT.PUT_LINE('Total mails count:'||mail_pkg.mailbox.count);
       --  MAIL_PKG.GET_HEADERS; -- Get headers for all mails
       
       FOR i IN 1..LEAST(10,mail_pkg.mailbox.count) LOOP -- GET FIRST 10 mails
         MAIL_PKG.GET_MAIL(i,0); -- GET MAIL HEADER
         DBMS_OUTPUT.PUT_LINE('MAIL:'||i || ' (' ||trunc(mail_pkg.mailbox(i).bytes/1024) || 'Kbytes) From:'||mail_pkg.mailbox(i).MailFrom
                              ||' Subject:'||mail_pkg.mailbox(i).Subject
                              );
             
         IF mail_pkg.mailbox(i).bytes>1000000 THEN
           -- Delete mails over 1Mb
           MAIL_PKG.DELETE_MAIL(i);
         ELSE
           MAIL_PKG.GET_MAIL(i);
           DBMS_OUTPUT.PUT_LINE(substr('    Text:' ||mail_pkg.mailbox(i).message,1,255) );         
           DBMS_OUTPUT.PUT_LINE('    Attachments:' ||mail_pkg.mailbox(i).attachments.count);

           IF mail_pkg.mailbox(i).attachments.count>0 THEN
             FOR att IN 1..mail_pkg.mailbox(i).attachments.count LOOP
               -- Real Attachments 
               IF mail_pkg.mailbox(i).attachments(att).hdr.exists('Content-Disposition') 
                 AND INSTR(mail_pkg.mailbox(i).attachments(att).hdr('Content-Disposition'),'attachment')>0               
               THEN
                 DBMS_OUTPUT.PUT_LINE('    filename: '
                    ||mail_pkg.extract_value(mail_pkg.mailbox(i).attachments(att).hdr('Content-Disposition'),'filename')
                    ||', about '||trunc(dbms_lob.getlength(mail_pkg.mailbox(i).attachments(att).content)/1024) ||'Kbytes'                 
                   );
                 -- You can convert this CLOB into BLOB ans save it into database or as file  
                 -- mail_pkg.mailbox(i).attachments(att).content                   
                                    
               END IF; 
               -- Preview includes and text-attachments 
               IF  mail_pkg.mailbox(i).attachments(att).hdr.exists('Content-Type') THEN
                 IF  INSTR(mail_pkg.mailbox(i).attachments(att).hdr('Content-Type'),'text')>0 THEN
                   DBMS_OUTPUT.PUT_LINE(substr('    PreviewAttachmentText:' ||mail_pkg.mailbox(i).attachments(att).content,1,255) );             
                 END IF;
               END IF;  
             END LOOP;
           END IF;                           
         END IF;     
       END LOOP;
   
       MAIL_PKG.MAIL_DISCONNECT;
    EXCEPTION WHEN OTHERS THEN
      -- ANYCASE YOU MUST CLOSE CONNECTION
      MAIL_PKG.MAIL_DISCONNECT;
    END;       
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37960275
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И, собственно, новая версия пакета.
Принимаю ваши замечания и предложения :)


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
521.
522.
523.
524.
525.
526.
527.
528.
529.
530.
531.
532.
533.
534.
535.
536.
537.
538.
539.
540.
541.
542.
543.
544.
545.
546.
547.
548.
549.
550.
551.
552.
553.
554.
555.
556.
557.
558.
559.
560.
561.
562.
563.
564.
565.
566.
567.
568.
569.
570.
571.
572.
573.
574.
575.
576.
577.
578.
579.
580.
581.
582.
583.
584.
585.
586.
587.
588.
589.
590.
591.
592.
593.
594.
595.
596.
597.
598.
599.
600.
601.
602.
603.
604.
605.
606.
607.
608.
609.
610.
611.
612.
613.
614.
615.
616.
617.
618.
619.
620.
621.
622.
623.
624.
625.
626.
627.
628.
629.
630.
631.
632.
633.
634.
635.
636.
637.
638.
639.
640.
641.
642.
643.
644.
645.
646.
647.
648.
649.
650.
651.
652.
653.
654.
655.
656.
657.
658.
659.
660.
661.
662.
663.
664.
665.
666.
667.
668.
669.
670.
671.
672.
673.
674.
675.
676.
677.
678.
679.
680.
681.
682.
683.
684.
685.
686.
687.
688.
689.
690.
691.
692.
693.
694.
695.
696.
697.
698.
699.
700.
701.
702.
703.
704.
705.
706.
707.
708.
709.
710.
711.
712.
713.
714.
715.
716.
717.
718.
719.
720.
721.
722.
723.
724.
725.
726.
727.
728.
729.
730.
731.
732.
733.
734.
735.
736.
737.
738.
739.
740.
741.
742.
743.
744.
745.
746.
747.
748.
749.
750.
751.
752.
753.
754.
755.
756.
757.
758.
759.
760.
761.
762.
763.
764.
765.
766.
767.
768.
769.
770.
771.
772.
773.
774.
775.
776.
777.
778.
779.
780.
781.
782.
783.
784.
785.
786.
787.
788.
789.
790.
791.
792.
793.
794.
795.
796.
797.
798.
799.
800.
801.
802.
803.
804.
805.
806.
807.
808.
809.
810.
811.
812.
813.
814.
815.
816.
817.
818.
819.
820.
821.
822.
823.
824.
825.
826.
827.
828.
829.
830.
831.
832.
833.
834.
835.
836.
837.
838.
839.
840.
841.
842.
843.
844.
845.
846.
847.
848.
849.
850.
851.
852.
853.
854.
855.
856.
857.
858.
859.
860.
861.
862.
863.
864.
865.
866.
867.
868.
869.
870.
871.
872.
873.
874.
875.
876.
877.
878.
879.
880.
881.
882.
883.
884.
885.
886.
887.
888.
889.
890.
891.
892.
893.
894.
895.
896.
897.
898.
899.
900.
901.
902.
903.
904.
905.
906.
907.
908.
909.
910.
911.
912.
913.
914.
915.
916.
917.
918.
919.
920.
921.
922.
923.
924.
925.
926.
927.
928.
929.
930.
931.
932.
933.
934.
935.
936.
937.
938.
939.
940.
941.
CREATE OR REPLACE PACKAGE MAIL_PKG IS
-- --------------------------------------------------------------------------
-- Name         : MAIL_PKG
-- Author       : Nekrasov Alexander
-- Description  : Mail package, send email with attachments
-- Url          : http://www.sql.ru/forum/actualthread.aspx?tid=729238
-- Ammedments   :
--   When         Who         What
--   ===========  ==========  =================================================
--   22-JAN-2010  Nekrasov A.  Initial Creation
--   11-OCT-2010  Nekrasov A.  Add Blob attachments
--   17-SEP-2012  Nekrasov A.  Add Receive Emails
-- --------------------------------------------------------------------------

/* EXAMPLE:

 1) Short text email
    BEGIN
      MAIL_PKG.SEND( 'a.ivanov@yourcomany.ru','Test subject', 'Some message!');
	END;

 2) Send mail with text message over 32kbytes formed with CLOB 
    DECLARE 
      v clob:='Some text message over 32kb'||chr(10)||chr(13);
      t varchar2(255):=' The quick brown fox jumps over the lazy dog. '
                     ||' The quick brown fox jumps over the lazy dog. '
                     ||' The quick brown fox jumps over the lazy dog. '||chr(10)||chr(13);
    BEGIN
      for x in 1..300 loop
        v:=v||to_char(x)||' '||t;
      end loop;
      MAIL_PKG.SEND( 'a.ivanov@yourcompany.ru','Test subject', v);
    END ;  

 3) Send mail with message over 32kbytes formed with BLOB
    DECLARE
      vBlob BLOB;
  	BEGIN
	 SELECT file_data INTO vBlob FROM FND_LOBS WHERE FILE_ID = 161005;						
	 MAIL_PKG.ADD_ATTACHMENT( vBlob
							 ,'MessageOver32kb.htm'
							 ,'text/html'
							);							
      MAIL_PKG.SEND( 'a.ivanov@yourcomany.ru','Big message', NULL);	
	END;
	
 4) Extension Email with attacments
    DECLARE
      vBlob BLOB;
    BEGIN
	 MAIL_PKG.SET_MAILSERVER ('localhost',25);
	 MAIL_PKG.SET_AUTH ('a.nekrasov','password');

	 -- Add attachment from file 
	 MAIL_PKG.ADD_ATTACHMENT( 'ODPDIR'
							 ,'girl3d.jpeg'
							 ,'image/jpeg'
							);

	 -- Add attachment from BLOB	
	 SELECT file_data INTO vBlob FROM FND_LOBS WHERE FILE_ID = 161005;						
	 MAIL_PKG.ADD_ATTACHMENT( vBlob
							 ,'ReportResult.htm'
							 ,'text/html'
							);							

	 MAIL_PKG.SEND( mailto => 'A. Ivanov <a.ivanov@yourcomany.ru>;, O.Petrov <o.petrov@yourcompany.ru>;'
	              , subject => 'Test subject'
				  , message => 'Some <b>bold</b> message!'
				  , mailfrom => 'Oracle Notify <no-reply@yourcompany.ru>;'
                  , mimetype => 'text/html'
				  , priority => 1
	              );
	END;
    
 5) Receive emails example:
 
    BEGIN
       MAIL_PKG.DEBUG := TRUE;
       MAIL_PKG.SET_MAILSERVER ('yourmailserver.com');
       MAIL_PKG.SET_AUTH ('a.ivanov','mypass');
       MAIL_PKG.MAIL_CONNECT;
       DBMS_OUTPUT.PUT_LINE('Total mails count:'||mail_pkg.mailbox.count);
       --  MAIL_PKG.GET_HEADERS; -- Get headers for all mails
       
       FOR i IN 1..LEAST(10,mail_pkg.mailbox.count) LOOP -- GET FIRST 10 mails
         MAIL_PKG.GET_MAIL(i,0); -- GET MAIL HEADER
         DBMS_OUTPUT.PUT_LINE('MAIL:'||i || ' (' ||trunc(mail_pkg.mailbox(i).bytes/1024) || 'Kbytes) From:'||mail_pkg.mailbox(i).MailFrom
                              ||' Subject:'||mail_pkg.mailbox(i).Subject
                              );
             
         IF mail_pkg.mailbox(i).bytes>1000000 THEN
           -- Delete mails over 1Mb
           MAIL_PKG.DELETE_MAIL(i);
         ELSE
           MAIL_PKG.GET_MAIL(i);
           DBMS_OUTPUT.PUT_LINE(substr('    Text:' ||mail_pkg.mailbox(i).message,1,255) );         
           DBMS_OUTPUT.PUT_LINE('    Attachments:' ||mail_pkg.mailbox(i).attachments.count);

           IF mail_pkg.mailbox(i).attachments.count>0 THEN
             FOR att IN 1..mail_pkg.mailbox(i).attachments.count LOOP
               -- Real Attachments 
               IF mail_pkg.mailbox(i).attachments(att).hdr.exists('Content-Disposition') 
                 AND INSTR(mail_pkg.mailbox(i).attachments(att).hdr('Content-Disposition'),'attachment')>0               
               THEN
                 DBMS_OUTPUT.PUT_LINE('    filename: '
                    ||mail_pkg.extract_value(mail_pkg.mailbox(i).attachments(att).hdr('Content-Disposition'),'filename')
                    ||', about '||trunc(dbms_lob.getlength(mail_pkg.mailbox(i).attachments(att).content)/1024) ||'Kbytes'                 
                   );
                 -- You can convert this CLOB into BLOB ans save it into database or as file  
                 -- mail_pkg.mailbox(i).attachments(att).content                   
                                    
               END IF; 
               -- Preview includes and text-attachments 
               IF  mail_pkg.mailbox(i).attachments(att).hdr.exists('Content-Type') THEN
                 IF  INSTR(mail_pkg.mailbox(i).attachments(att).hdr('Content-Type'),'text')>0 THEN
                   DBMS_OUTPUT.PUT_LINE(substr('    PreviewAttachmentText:' ||mail_pkg.mailbox(i).attachments(att).content,1,255) );             
                 END IF;
               END IF;  
             END LOOP;
           END IF;                           
         END IF;     
       END LOOP;
   
       MAIL_PKG.MAIL_DISCONNECT;
    EXCEPTION WHEN OTHERS THEN
      -- ANYCASE YOU MUST CLOSE CONNECTION
      MAIL_PKG.MAIL_DISCONNECT;
    END;       
*/

 POP3 CONSTANT VARCHAR2(4):='POP3';
 SMTP CONSTANT VARCHAR2(4):='SMTP';
 IMAP CONSTANT VARCHAR2(4):='IMAP';

 DEBUG_ALL CONSTANT INT := 0;
 DEBUG_MESSAGES CONSTANT INT := 1;
 DEBUG_WARNINGS CONSTANT INT := 2;
 DEBUG_ERRORS CONSTANT INT := 3; 

 DEBUG BOOLEAN := FALSE;
 DEBUG_LEVEL NUMBER := DEBUG_WARNINGS;

 -- SET_MAILSERVER:
 --  Set up mail server for send emails. Default Localhost
 -- IN
 -- MAILSERVER is ip or url of mail server
 -- MAILPORT is port for mail server. Default 25
 PROCEDURE SET_MAILSERVER ( mailserver varchar2
                          , mailport number default 25
                          );

 -- SET_AUTH
 --  Set authorization on smtp server
 -- IN
 -- AUTH_USER is authorization user
 -- AUTH_PASS is password for AUTH_USER
 --
 -- Execute SET_AUTH(); -- for disable authorization
 PROCEDURE SET_AUTH (  auth_user varchar2 default null
                     , auth_pass varchar2 default null
                          );

 -- ENCODE:
 --  Encodes string to email compatible view
 -- IN
 -- STR is string to convert
 -- TP is type of convert:
 --    B - is base64 encoding
 FUNCTION ENCODE( str IN VARCHAR2
                , tp IN VARCHAR2 DEFAULT 'Q') RETURN VARCHAR2;

 -- PREPARE
 --  Prepare configs for email.
 PROCEDURE PREPARE;

 -- ADD_RCPT
 --  Add recipient to recipients list exploded by  ','
 -- STR is variable with recipients
 -- RCPTMAIL is recipient mail added to STR
 -- RCPTNAME is recipient name added to STR
 -- Example: str='user1@domain.ru' rcptmail='user2@domain.ru'
 --  after => str='user1@domain.ru, user2@domain.ru'
 PROCEDURE ADD_RCPT( str IN OUT VARCHAR2
                   , rcptmail IN VARCHAR2
				   , rcptname IN VARCHAR2 DEFAULT NULL);

 -- ADD_ATTACHMENT
 --  Add file-attachment to attachments list to email
 -- IN
 -- DIRNAME is logical link to access physical directories of server. See DBA_DIRECTORIES table
 -- FILENAME is name of file to attach
 -- MIMETYPE is mime-type for sended file
 -- NAME is name for attached file for email. Default eq FILENAME
 PROCEDURE ADD_ATTACHMENT ( dirname IN varchar2
                          , filename IN varchar2
						  , mimetype IN varchar2 DEFAULT 'text/plain'
                          , name IN varchar2 DEFAULT NULL
                           );
 -- ADD_ATTACHMENT
 --  Add blob-attachment to attachments list to email
 -- IN
 -- BLOBLOC - Blob locator for attached blob
 -- FILENAME is name of file to attach
 -- MIMETYPE is mime-type for sended file
 PROCEDURE ADD_ATTACHMENT ( blobloc IN blob
                          , filename IN varchar2
						  , mimetype IN varchar2 DEFAULT 'text/html'
                           );
						   
 -- SEND
 --  Send email with attachments to recipient
 -- IN
 -- MAILTO is name and email addresses of recipients ( ex. "user@domain.com"
 --       , "User Name <user@domain.com>;", "User1 <user1@domain>;, User2 <user2@domain>;")
 -- SUBJECT is subject of email
 -- MESSAGE is message of email
 -- MAILFROM is name and email of sender. (ex. "no-reply@domain", "Notify system <no-reply@domain>;")
 -- MIMETYPE is mime-type of message. Available values is 'text/plain' and 'text/html'
 -- PRIORITY is priority of mail (1 - High, 2 - Highest, 3 - Normal, 4 - Lowest, 5 - Low)
 PROCEDURE SEND ( mailto IN VARCHAR2
				, subject IN VARCHAR2
				, message IN CLOB
                , mailfrom IN VARCHAR2 DEFAULT NULL
				, mimetype IN VARCHAR2 DEFAULT 'text/plain'
				, priority IN NUMBER DEFAULT NULL
                );

 FUNCTION DECODE_CHARSET (str IN VARCHAR2, charset varchar2) RETURN VARCHAR2;
 
 FUNCTION MIME_DECODE(str IN VARCHAR2) RETURN VARCHAR2;

 FUNCTION extract_value(str IN VARCHAR2,entity IN VARCHAR2) RETURN VARCHAR2;

 TYPE T_HDR IS TABLE OF VARCHAR2(32717) INDEX BY VARCHAR2(2555);				
 
 TYPE T_ATTACHMENT IS RECORD ( boundary varchar2(255)
                          , ContentTransferEncoding varchar2(25)
                          , charset varchar2(25)
                          , hdr t_hdr
                          , content clob
                           );
 
 TYPE T_ATTACHMENTS IS TABLE OF T_ATTACHMENT;

 TYPE MESSAGE IS RECORD( hdr              t_hdr
                        ,MailFrom         varchar2(32717)
                        ,MailTo           varchar2(32717)
                        ,ReturnPath       varchar2(32717)
                        ,Subject          varchar2(32717)
                        ,MailDate         DATE
                        ,message          CLOB
                        ,bytes            number
                        ,ContentTransferEncoding varchar2(25)
                        ,charset          varchar2(25)
                        ,attachments         t_attachments := t_attachments()                                                                         
                       );			
					   
 TYPE MAILBOXT IS TABLE OF MESSAGE INDEX BY PLS_INTEGER;				
 MAILBOX MAILBOXT;			
 	
 FUNCTION PARSE_LINE (line varchar2, ContentTransferEncoding varchar2, charset varchar2 default null) RETURN varchar2; 
  
 PROCEDURE MAIL_CONNECT;
 
 PROCEDURE MAIL_DISCONNECT;
 			
 PROCEDURE GET_HEADERS;		

 PROCEDURE GET_MAIL(mail_id number,lines number default null);	
 
 PROCEDURE DELETE_MAIL(mail_id number);	
 
END MAIL_PKG;
/

CREATE OR REPLACE PACKAGE BODY MAIL_PKG
IS

 mailserver VARCHAR2(30):='localhost';
 mailport INTEGER:=25;
 auth_user VARCHAR2(50);
 auth_pass VARCHAR2(50);
 crlf         VARCHAR2(2)  := utl_tcp.CRLF; -- chr(13)||chr(10);

 c  utl_tcp.connection;  -- TCP/IP connection to the Web server (for pop3)

 type attach_row is record ( dirname varchar2(30)
                           , filename  varchar2(30)
                           , name  varchar2(30)
						   , mimetype varchar2(30)
						   , blobloc blob
						   , attachtype varchar2(30)
                           );
 type attach_list is table of attach_row;
 attachments attach_list;

 type rcpt_row is record ( rcptname varchar2(100)
                     , rcptmail varchar2(50)
					 );
 type rcpt_list is table of rcpt_row;

 PROCEDURE SET_MAILSERVER ( mailserver varchar2
                          , mailport number default 25
                          ) IS
 BEGIN
  MAIL_PKG.mailserver := mailserver;
  MAIL_PKG.mailport := mailport;
 END;

 PROCEDURE SET_AUTH (  auth_user varchar2 default null
                     , auth_pass varchar2 default null
                          ) IS
 BEGIN
   MAIL_PKG.auth_user := auth_user;
   MAIL_PKG.auth_pass := auth_pass;
 END;

 FUNCTION ENCODE(str IN VARCHAR2, tp IN VARCHAR2 DEFAULT 'Q') RETURN VARCHAR2 IS
 BEGIN
   -- ToDo: UTL_ENCODE.QUOTED_PRINTABLE | UTL_ENCODE.BASE64
   IF tp='B' THEN
     RETURN '=?utf-8?b?'|| UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw (CONVERT (SUBSTR(str,1,24), 'UTF8'))))|| '?='
	     || CASE WHEN SUBSTR(str,25) IS NOT NULL THEN crlf || ' '|| ENCODE(SUBSTR(str,25),tp) END;
   ELSIF tp='Q' THEN
     RETURN '=?utf-8?q?' || UTL_RAW.cast_to_varchar2(utl_encode.QUOTED_PRINTABLE_ENCODE(utl_raw.cast_to_raw(CONVERT (SUBSTR(str,1,8), 'UTF8') ))) || '?='
	     || CASE WHEN SUBSTR(str,9) IS NOT NULL THEN crlf || ' '|| ENCODE(SUBSTR(str,9),tp) END;
   ELSE
     RETURN str;
   END IF;
 END;
 
 FUNCTION DECODE_CHARSET (str IN VARCHAR2, charset varchar2) RETURN VARCHAR2 IS
 BEGIN
   return CONVERT(str,SUBSTR(USERENV ('language'),INSTR(USERENV ('language'),'.')+1)
                   , CASE lower(charset) WHEN 'koi8-r' THEN 'CL8KOI8R'
                                  WHEN 'utf-8' THEN 'UTF8'
                     ELSE SUBSTR(USERENV ('language'),INSTR(USERENV ('language'),'.')+1)
                     END
                   );
 END;
 
 FUNCTION MIME_DECODE(str IN VARCHAR2) RETURN VARCHAR2 IS
   strout VARCHAR2(32717);
  buff varchar2(32717);
 text varchar2(32717);
 encode_method varchar2(1);
 charset varchar2(25);
BEGIN
  strout := str;
  LOOP
    IF instr(strout,'=?')>0 and instr(strout,'?=')>0 and instr(strout,'?=') > instr(strout,'=?') then
      buff := substr(substr(strout,instr(strout,'=?')),1,1+instr(substr(strout,instr(strout,'=?')),'?=',instr(substr(strout,instr(strout,'=?')),'?',1,3)+1 ));      
      charset := lower(substr(buff,3, instr(substr(buff,3),'?')-1));
      encode_method := substr(buff, 4+length(charset),1);
      text := substr(buff,instr(buff,'?',1,3)+1, instr(buff,'?',1,4)-instr(buff,'?',1,3)-1);
      IF  encode_method = 'B' THEN
       text := UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_decode(UTL_RAW.cast_to_raw(text)));
      ELSE
       text := UTL_RAW.cast_to_varchar2(utl_encode.quoted_printable_decode(UTL_RAW.cast_to_raw(replace(text,'_',' '))));   
      END IF;
      text := DECODE_CHARSET(text,charset); 
      strout:=REPLACE(strout,buff,text);                   
    ELSE
       EXIT;                
    END IF;
  END LOOP;      
    RETURN strout;
 END;

 PROCEDURE extract_value(val IN OUT varchar2, str IN VARCHAR2,entity IN VARCHAR2) 
 IS
  buff varchar2(255);
  returnval varchar2(255);
 BEGIN
    if instr(str,entity)=0 
    then
     return;
    else
     val := replace(substr(str,length(entity)+1+instr(str,entity||'='), instr(substr(str||';',length(entity)+1+instr(str,entity||'=')),';')-1),'"','');
    end if;
 END;

 FUNCTION extract_value(str IN VARCHAR2,entity IN VARCHAR2) RETURN VARCHAR2 IS
  p_val varchar2(32717):='';
 BEGIN
   mail_pkg.extract_value(p_val ,str ,entity );
   return p_val; 
 END;


 PROCEDURE PREPARE
 IS
 BEGIN
   MAIL_PKG.attachments:=MAIL_PKG.attach_list();
 END;

 PROCEDURE ADD_RCPT( str IN OUT VARCHAR2
                   , rcptmail IN VARCHAR2
				   , rcptname IN VARCHAR2 DEFAULT NULL) IS
  rcpt varchar2(255);
 BEGIN
  rcpt:=CASE WHEN rcptname is null THEN
          ' <'|| rcptmail ||'>' --rcptmail
		ELSE
		  trim(replace(replace(rcptname,',',' '),';',' '))||' <'|| rcptmail ||'>'
		END;
  IF trim(str) is NULL THEN
     str :=  trim(rcpt);
  ELSE
     str := str||', '||trim(rcpt);
  END IF;
 END;

 PROCEDURE ADD_ATTACHMENT ( dirname IN varchar2
                          , filename IN varchar2
						  , mimetype IN varchar2 DEFAULT 'text/plain'
                          , name IN varchar2 DEFAULT NULL
                           )
 IS
  v_fl BFILE :=BFILENAME(dirname,filename);
 BEGIN
   IF DBMS_LOB.FILEEXISTS (v_fl)=1 THEN
      MAIL_PKG.attachments.extend;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).dirname:=dirname;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).filename:=filename;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).name:=nvl(name,filename);
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).mimetype:=mimetype;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).attachtype:='FILE';	  
   ELSE
      RAISE_APPLICATION_ERROR(-20001, 'File is not exists');
   END IF;
 END;
 
 PROCEDURE ADD_ATTACHMENT ( blobloc IN blob
                          , filename IN varchar2
						  , mimetype IN varchar2 DEFAULT 'text/html'
                           )
 IS 
 BEGIN
      MAIL_PKG.attachments.extend;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).name:=filename;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).mimetype:=mimetype;
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).blobloc:=blobloc;	  
      MAIL_PKG.attachments(MAIL_PKG.attachments.count).attachtype:='BLOB';	  
 END; 						   
 

 FUNCTION CREATE_RCPT_LIST(mailto IN VARCHAR2) RETURN MAIL_PKG.rcpt_list IS
  v_mailto VARCHAR2(4096) := replace(mailto,';',',')||',';
  pntr INTEGER;
  buf VARCHAR2(255);
  rcptmail VARCHAR2(255);
  rcptlist MAIL_PKG.rcpt_list:=MAIL_PKG.rcpt_list();
 BEGIN
  FOR maxrcptnts IN 1..50
  LOOP
     pntr:=INSTR(v_mailto,','); buf := substr(v_mailto,1,pntr-1);
     IF pntr>0 THEN
	   IF INSTR(buf,'<')>0 AND INSTR(buf,'>')>0 THEN
	     rcptmail:= SUBSTR(buf,INSTR(buf,'<')+1,INSTR(SUBSTR(buf,INSTR(buf,'<')+1),'>')-1);
		 IF rcptmail IS NOT NULL THEN
	        rcptlist.extend;
		    rcptlist(rcptlist.count).rcptmail := TRIM(rcptmail);
		    rcptlist(rcptlist.count).rcptname := TRIM(SUBSTR(buf,1,INSTR(buf,'<')-1));
	     END IF;
       ELSE
	     rcptmail := TRIM(buf);
		 IF rcptmail IS NOT NULL THEN
           rcptlist.extend;
		   rcptlist(rcptlist.count).rcptmail:= TRIM(rcptmail);
		 END IF;
	   END IF;
	 ELSE
	   EXIT;
	 END IF;
	 v_mailto := substr(v_mailto,pntr+1);
   END LOOP;
   RETURN rcptlist;
 END;

 PROCEDURE SEND ( mailto IN VARCHAR2
				, subject IN VARCHAR2
				, message IN CLOB
                , mailfrom IN VARCHAR2 DEFAULT NULL
				, mimetype IN VARCHAR2 DEFAULT 'text/plain'
				, priority IN NUMBER DEFAULT NULL
                )
 IS
   v_Mail_Conn  utl_smtp.Connection;
   boundary VARCHAR2(50) := '-----7D81B75CCC90DFRW4F7A1CBD';
   vFile BFILE;
   vRAW RAW(32767);
   amt CONSTANT BINARY_INTEGER := 10368; -- 48bytes binary convert to 128bytes of base64. (32767/2 max for raw convert)
   v_amt BINARY_INTEGER;
   ps BINARY_INTEGER := 1;
   message_part varchar2(32767);
   v_mime VARCHAR2(30);
   reply UTL_SMTP.REPLY;
   replies UTL_SMTP.REPLIES;
   rcptlist MAIL_PKG.rcpt_list;
   sndr MAIL_PKG.rcpt_row;
 BEGIN
    rcptlist:=create_rcpt_list(mailto);
	IF rcptlist.count=0 THEN
      RAISE_APPLICATION_ERROR(-20001, 'Recipients requered');
	END IF;
    IF mimetype<>'text/html' and mimetype<>'text/plain' THEN
      RAISE_APPLICATION_ERROR(-20001, 'MimeType must be "text/html" or "text/plain"');
    ELSE
      v_mime:=mimetype;
    END IF;
    v_Mail_Conn := utl_smtp.Open_Connection(MAIL_PKG.mailserver, MAIL_PKG.mailport);
    replies:=utl_smtp.Ehlo(v_Mail_Conn,MAIL_PKG.mailserver);
	if create_rcpt_list(mailfrom).count>0 then
	  sndr := create_rcpt_list(mailfrom)(1);
	else
	  sndr := create_rcpt_list( 'mail@' || UTL_INADDR.GET_HOST_NAME )(1); -- host from oracle-server
	  -- sndr := create_rcpt_list( 'mail@' || substr(replies(1).text,1,instr(replies(1).text,' ')-1))(1); -- Addr from ehlo answer
    end if;

    if mail_pkg.auth_user is not null then
       for x IN 1 .. replies.count loop
 	     IF INSTR(replies(x).text,'AUTH')>0 then -- If server supply authorization
            utl_smtp.command(v_Mail_Conn, 'AUTH LOGIN');
            utl_smtp.command(v_Mail_Conn,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(auth_user))));
            utl_smtp.command(v_Mail_Conn,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(auth_pass))));
			exit;
		 END IF;
	   end loop;
    end if;

    utl_smtp.Mail(v_Mail_Conn, sndr.rcptmail);
    FOR rcpts IN 1 .. rcptlist.count
	LOOP
	  utl_smtp.Rcpt(v_Mail_Conn, rcptlist(rcpts).rcptmail);
	END LOOP;

    utl_smtp.open_data(v_Mail_Conn); -- open data sheet
    utl_smtp.write_data(v_Mail_Conn, 'Date: ' || TO_CHAR(SYSTIMESTAMP,'Dy, DD Mon YYYY HH24:MI:SS TZHTZM','NLS_DATE_LANGUAGE = ''american''') || crlf);
    utl_smtp.write_data(v_Mail_Conn, 'From: ');
	if sndr.rcptname is not null then
        utl_smtp.write_data(v_Mail_Conn, MAIL_PKG.ENCODE(sndr.rcptname) ||' <'|| sndr.rcptmail || '>');
	else
        utl_smtp.write_data(v_Mail_Conn, sndr.rcptmail);
	end if;
    utl_smtp.write_data(v_Mail_Conn, crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Subject: '|| MAIL_PKG.ENCODE(subject) || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'To: ');
    FOR rcpts IN 1 .. rcptlist.count
	LOOP
	  if rcpts>1 then
       utl_smtp.write_data(v_Mail_Conn, ',');
	  end if;
	  if rcptlist(rcpts).rcptname is not null then
        utl_smtp.write_data(v_Mail_Conn, MAIL_PKG.ENCODE(rcptlist(rcpts).rcptname) ||' <'|| rcptlist(rcpts).rcptmail || '>');
	  else
        utl_smtp.write_data(v_Mail_Conn, rcptlist(rcpts).rcptmail);
	  end if;
	END LOOP;
    utl_smtp.write_data(v_Mail_Conn, crlf );

	IF priority IS NOT NULL and priority BETWEEN 1 AND 5 THEN
      utl_smtp.write_data(v_Mail_Conn, 'X-Priority: ' || priority || crlf );
	END IF;
    utl_smtp.write_data(v_Mail_Conn, 'MIME-version: 1.0' || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Type: multipart/mixed;'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, ' boundary="'||boundary||'"'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );
 
    --Message
	IF message IS NOT NULL THEN	
    utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||v_mime||'; charset="utf-8"'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Transfer-Encoding: 8bit'|| crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );
    -- utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(CONVERT(message,'UTF8')));
    ps:=1; v_amt:=amt;
    LOOP
      BEGIN
        dbms_lob.read(message, v_amt, ps, message_part);
        ps := ps + v_amt;
        utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(CONVERT(message_part,'UTF8')));                 
      EXCEPTION
        WHEN no_data_found THEN
             EXIT;
      END;            
    END LOOP; 
    utl_smtp.write_data(v_Mail_Conn, crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );
    END IF;
	
	--Attachments
	IF MAIL_PKG.attachments.count>0 THEN
	  FOR x IN 1 .. MAIL_PKG.attachments.count LOOP
          utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
		  -- HOTFIX
		  IF message IS NOT NULL OR x!=1 THEN
            utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||MAIL_PKG.attachments(x).mimetype||';'|| crlf );
            utl_smtp.write_data(v_Mail_Conn, ' name="');
	        utl_smtp.write_raw_data(v_Mail_Conn,utl_raw.cast_to_raw(MAIL_PKG.attachments(x).name));
            utl_smtp.write_data(v_Mail_Conn, '"' || crlf);
            utl_smtp.write_data(v_Mail_Conn, 'Content-Transfer-Encoding: base64'|| crlf );
            utl_smtp.write_data(v_Mail_Conn, 'Content-Disposition: attachment;'|| crlf );
            utl_smtp.write_data(v_Mail_Conn, ' filename="' || MAIL_PKG.ENCODE(MAIL_PKG.attachments(x).name) || '"' || crlf);
		  ELSE
           utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||MAIL_PKG.attachments(x).mimetype||'; charset="utf-8"'|| crlf );
           utl_smtp.write_data(v_Mail_Conn, 'Content-Transfer-Encoding: base64'|| crlf );
          END IF;			
          utl_smtp.write_data(v_Mail_Conn, crlf );
		  IF MAIL_PKG.attachments(x).attachtype = 'FILE' THEN 
             vFile := BFILENAME(MAIL_PKG.attachments(x).dirname,MAIL_PKG.attachments(x).filename);
		     dbms_lob.fileopen(vFile, dbms_lob.file_readonly);
             ps:=1; v_amt:=amt;
		     LOOP
		       BEGIN
		         dbms_lob.read (vFile, v_amt, ps, vRAW);
			     ps := ps + v_amt;
                 utl_smtp.write_raw_data(v_Mail_Conn, UTL_ENCODE.base64_encode(vRAW));
		       EXCEPTION
                 WHEN no_data_found THEN
			       EXIT;
			   END;			
		     END LOOP;
		     dbms_lob.fileclose(vFile);
		  ELSIF MAIL_PKG.attachments(x).attachtype = 'BLOB' THEN
		  	 dbms_lob.open(MAIL_PKG.attachments(x).blobloc, dbms_lob.file_readonly);
             ps:=1; v_amt:=amt;
		     LOOP
		       BEGIN
		         dbms_lob.read (MAIL_PKG.attachments(x).blobloc, v_amt, ps, vRAW);
			     ps := ps + v_amt;
                 utl_smtp.write_raw_data(v_Mail_Conn, UTL_ENCODE.base64_encode(vRAW));
		       EXCEPTION
                 WHEN no_data_found THEN
			       EXIT;
			   END;			
		     END LOOP;
		     dbms_lob.close(MAIL_PKG.attachments(x).blobloc);					  	 
		  END IF;		 		  

          utl_smtp.write_data(v_Mail_Conn, crlf );
          utl_smtp.write_data(v_Mail_Conn, crlf );
	  END LOOP;
	END IF;

    -- Final Boundary
    utl_smtp.write_data(v_Mail_Conn, '--' || boundary || '--');

    utl_smtp.close_data(v_Mail_Conn);
    utl_smtp.quit(v_Mail_Conn);

	-- Clear attachments
    MAIL_PKG.attachments:=MAIL_PKG.attach_list();

 EXCEPTION
    WHEN OTHERS THEN
       BEGIN
         MAIL_PKG.attachments:=MAIL_PKG.attach_list();
		 utl_smtp.rset(v_Mail_Conn);
	     utl_smtp.quit(v_Mail_Conn);
	   EXCEPTION WHEN OTHERS THEN NULL;
	   END;
	RAISE;
 END;

 PROCEDURE PDEBUG(mess IN varchar2, plevel IN NUMBER DEFAULT 0) IS
 BEGIN
   IF MAIL_PKG.DEBUG AND plevel>=MAIL_PKG.DEBUG_LEVEL THEN
     dbms_output.put_line(substr(mess,1,255));
   END IF;
 END;

 PROCEDURE CMD(c in out utl_tcp.connection, command in varchar2,status out varchar2, answer out varchar2) is
   ret_val pls_integer; 
--   pc 
   answr varchar2(32767); 
 begin
   ret_val := utl_tcp.write_line(c,command);
   answr := utl_tcp.get_line(c, TRUE);
   status := trim(substr(answr,1,instr(answr,' ')));
   answer := substr(answr,instr(answr,' ')+1);
   if mail_pkg.debug then
    PDEBUG('DEBUG:'||status||' '||answer,mail_pkg.debug_messages);
   end if;
   if status = '-ERR' then
     raise_application_error (-20000,answr);
   end if;
 end;
 
 FUNCTION PARSE_LINE (line varchar2, ContentTransferEncoding varchar2, charset varchar2 default null) RETURN varchar2 IS
  decoding_line varchar2(255);
 BEGIN
   decoding_line := line;
   IF decoding_line is null then return null; END IF;
   IF ContentTransferEncoding = 'base64' then
      decoding_line := UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_decode(UTL_RAW.cast_to_raw(decoding_line)));
   ELSIF ContentTransferEncoding = 'quoted-printable' then
      decoding_line := UTL_RAW.cast_to_varchar2(UTL_ENCODE.quoted_printable_decode(UTL_RAW.cast_to_raw(decoding_line)));   
   END IF;   
   decoding_line := DECODE_CHARSET(decoding_line,charset);
   
   RETURN decoding_line;
 EXCEPTION WHEN OTHERS THEN
   PDEBUG('ERR: PARSE:' || ContentTransferEncoding || ' ' || charset || ',' || line || ' > '||decoding_line, mail_pkg.debug_errors);
   RETURN NULL;   
 END;
 
 
 PROCEDURE MAIL_CONNECT IS
  p_ip varchar2(25);
  answer varchar2(32767);
  status varchar2(25);
  cnt number;
  bytes number;         
 BEGIN
  p_ip := UTL_INADDR.GET_HOST_ADDRESS(mailserver);
  c := utl_tcp.open_connection(remote_host => p_ip,
                               remote_port =>  110,
                               charset     => 'US7ASCII',
                               tx_timeout => 10);  -- open connection
  answer := utl_tcp.get_line(c, TRUE); 
  PDEBUG(answer,mail_pkg.debug_messages);  -- read result
  CMD(c,'USER '||MAIL_PKG.auth_user,status,answer);  
  CMD(c,'PASS '||MAIL_PKG.auth_pass,status,answer);
 BEGIN
  CMD(c,'STAT',status,answer);
  cnt := to_number(trim(substr(answer,1,instr(answer,' '))));
  bytes := to_number(trim(substr(answer,instr(answer,' ')))); 
  -- INIT ARRAY
  MAILBOX.DELETE;
  FOR mail_id IN 1 .. cnt  
  LOOP
       MAILBOX(mail_id).bytes := 0;        
  END LOOP;
 END;
    
 END;
 
 PROCEDURE MAIL_DISCONNECT IS
  answer varchar2(32767); 
  status varchar2(25); 
 BEGIN
   CMD(c,'QUIT',status,answer);  
   utl_tcp.close_connection(c);
 EXCEPTION WHEN OTHERS THEN
  BEGIN   
    utl_tcp.close_connection(c);
  EXCEPTION WHEN OTHERS THEN NULL;
  END;    
  RAISE;
 END;

 PROCEDURE GET_HEADERS IS 
  answer varchar2(32767);
  status varchar2(25);  
  cnt number;
  bytes number;     
 BEGIN
  CMD(c,'STAT',status,answer);
  cnt := to_number(trim(substr(answer,1,instr(answer,' '))));
  bytes := to_number(trim(substr(answer,instr(answer,' ')))); 
  -- GET MESSAGE SUBJECTS
  FOR mail_id IN 1 .. cnt -- cnt --1 ..  cnt 
  LOOP
       GET_MAIL(mail_id,0);   -- ,0 !!!!!        
  END LOOP;
 END;

 
 PROCEDURE GET_MAIL(mail_id number,lines number default null) IS
  answer varchar2(32767);
  cnt number;
  bytes number;
  status varchar2(25);
  message_body clob;
  hdr_flag boolean;
  hdr_entity varchar2(255);
  hdr_entity_value varchar2(32717);  
  boundary varchar2(128);
  part_header_flag boolean:=false;
  any_boundary_found boolean:=false;
  any_boundary_found_close boolean:=false;
 BEGIN     
 
       CMD(c,'LIST '||mail_id,status,answer); -- get message size
       MAILBOX(mail_id).bytes:=to_number(trim(substr(answer,instr(answer,' '))));

       IF  MAILBOX(mail_id).bytes >= 1048576 THEN             
           PDEBUG('BUG: Message '|| mail_id ||' over 1Mb, ' ||  MAILBOX(mail_id).bytes || ' bytes' ,mail_pkg.debug_errors);
       END IF;
       
       CMD(c,CASE WHEN lines is NULL THEN 'RETR '||mail_id ELSE 'TOP '||mail_id||' 10' END,status,answer); -- read message headers
       BEGIN
         hdr_entity:='';hdr_entity_value:=''; 
         hdr_flag := true;
         if lines<>0 or lines is null then
            MAILBOX(mail_id).message:='';
            MAILBOX(mail_id).attachments := t_attachments();            
         end if;
         dbms_lob.createtemporary(lob_loc => MAILBOX(mail_id).message, cache => true, dur => dbms_lob.call);                                  
         LOOP
             answer :=utl_tcp.get_line(c, TRUE);  -- read result
             EXIT WHEN answer = '.';             
             IF answer IS NULL THEN hdr_flag := false; END IF;
             IF hdr_flag THEN
                 IF ascii(substr(answer,0,1)) NOT IN (9,32) THEN
                   hdr_entity := substr(answer,1,instr(answer,':')-1);
                   MAILBOX(mail_id).HDR(hdr_entity):='';                                    
                   hdr_entity_value := substr(answer,instr(answer,':')+2);
                 ELSE 
                   hdr_entity_value := answer;  
                 END IF;

                 PDEBUG('HDR:'|| answer);              
                 MAILBOX(mail_id).HDR(hdr_entity):= MAILBOX(mail_id).HDR(hdr_entity)
                                                 || MIME_DECODE(hdr_entity_value);  
                 IF hdr_entity = 'Content-Type' THEN
                   if instr(answer,'boundary="')>0 then
                      extract_value(boundary,answer,'boundary');                   
                   end if;                 
                 END IF;                                                                                                              
             ELSE   
                 any_boundary_found := false;
                 any_boundary_found_close := false;                 
                 IF MAILBOX(mail_id).attachments.count>0 THEN
                 FOR incls IN MAILBOX(mail_id).attachments.first .. MAILBOX(mail_id).attachments.last
                 LOOP 
                   if answer = '--' || MAILBOX(mail_id).attachments(incls).boundary then
                     any_boundary_found := true;
                   end if;
                   if answer = '--' || MAILBOX(mail_id).attachments(incls).boundary || '--' then
                     any_boundary_found_close := true;
                   end if;                   
                 END LOOP;
                 END IF;
                 
                 if boundary is not null and 
                    ( answer = '--' || boundary 
                      or
                      any_boundary_found
                    )
                     then
                    part_header_flag:=true;
                    MAILBOX(mail_id).attachments.extend();
                    dbms_lob.createtemporary(lob_loc => MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).content, cache => true, dur => dbms_lob.call);  
                 elsif boundary is not null and 
                   (  answer = '--' || boundary || '--'
                     or 
                     any_boundary_found_close
                   )
                     then
                       null;                   
                 elsif part_header_flag and answer is null then
                    part_header_flag:=false;
                 else
                    IF part_header_flag THEN
                       IF ascii(substr(answer,0,1)) NOT IN (9,32) THEN
                          hdr_entity := substr(answer,1,instr(answer,':')-1);
                          MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).HDR(hdr_entity):='';                                    
                          hdr_entity_value := substr(answer,instr(answer,':')+2);
                       ELSE 
                          hdr_entity_value := answer;  
                       END IF;
                       MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).HDR(hdr_entity):= 
                              MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).HDR(hdr_entity)
                           || MIME_DECODE(hdr_entity_value);
                       
                       IF hdr_entity = 'Content-Type' THEN
                          extract_value(MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).boundary,answer,'boundary');                       
                          extract_value(MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).charset,answer,'charset');
--                            PDEBUG(MAILBOX(mail_id).includes(MAILBOX(mail_id).includes.last).charset,mail_pkg.debug_messages);                                           
                       ELSIF hdr_entity = 'Content-Transfer-Encoding' THEN
                            MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).ContentTransferEncoding := hdr_entity_value;                         
                       END IF;                                                                                                              
                                                                             
                    ELSE 
                    
                       -- BUG: BIG messages is very slow and prc can get "[SYS/PERM] Fatal error: Lost connection to input stream"
                       IF MAILBOX(mail_id).bytes < 1048576 THEN 
                         IF MAILBOX(mail_id).attachments.count>0 THEN
                            IF length(answer)>0 THEN
                              DBMS_LOB.APPEND ( MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).content 
                              , PARSE_LINE( answer
                                           ,MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).ContentTransferEncoding
                                           ,MAILBOX(mail_id).attachments(MAILBOX(mail_id).attachments.last).charset)  
                              );
                            END IF;                         
                         ELSE 
                            IF length(answer)>0 THEN
                              DBMS_LOB.APPEND ( MAILBOX(mail_id).message  
                              , --PARSE_LINE( 
                                            answer
                                  --         ,ContentTransferEncoding
                                    --       ,charset)                                
                              );
                            END IF;                         
                         END IF;
                       END IF;
                                  
                    END IF;                  
                    PDEBUG(CASE part_header_flag WHEN TRUE THEN 'H' ELSE 'B' END || '-BODY:'||answer);                                   
                 end if;   
             END IF;
                        
         END LOOP;
       EXCEPTION
         WHEN OTHERS THEN 
         PDEBUG('ERR: GET MESSAGE ' ||mail_id || ' ERROR ',mail_pkg.debug_errors);         
         RAISE;
       END;
       IF MAILBOX(mail_id).HDR.EXISTS('From') THEN
          MAILBOX(mail_id).MailFrom := MAILBOX(mail_id).HDR('From');
       END IF;   
       IF MAILBOX(mail_id).HDR.EXISTS('MailTo') THEN
          MAILBOX(mail_id).MailTo := MAILBOX(mail_id).HDR('To');
       END IF;   
       IF MAILBOX(mail_id).HDR.EXISTS('Return-Path') THEN
          MAILBOX(mail_id).ReturnPath := MAILBOX(mail_id).HDR('Return-Path');
       END IF;
       IF MAILBOX(mail_id).HDR.EXISTS('Subject') THEN
          MAILBOX(mail_id).Subject := MAILBOX(mail_id).HDR('Subject');
       END IF;   
       IF MAILBOX(mail_id).HDR.EXISTS('Date') THEN
          BEGIN
            MAILBOX(mail_id).MailDate := TO_TIMESTAMP_TZ(MAILBOX(mail_id).HDR('Date'),'Dy, DD Mon YYYY HH24:MI:SS TZHTZM','NLS_DATE_LANGUAGE = ''american''');
          EXCEPTION WHEN OTHERS THEN NULL; END;   
       END IF;     
 END;
 
 PROCEDURE DELETE_MAIL(mail_id number) IS
  answer varchar2(32767);
  status varchar2(25);  
 BEGIN
   CMD(c,'DELE '||mail_id,status,answer); 
 END;  
    
BEGIN
  MAIL_PKG.attachments:=MAIL_PKG.attach_list();
END;
/
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37960289
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chameleon82- Получить вложения! (все вложения представлены как CLOB)может быть сейчас с этим получше, во времена outlook express проблем хватало, особенно с переадресованными между разными почтовыми клиентами писем. проблемой было даже понять, что из миме-партийцев является телом самого сообщения.

Java Mail API вполне стабильное решение.
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #37960323
SvDev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для сравнения

Отправка вложений:

CES package http://www.oracletips.info/email_files.htm,
примеры http://www.uaex.edu/bknox/using_ces.email_files.htm

Прием вложений:

http://plsqlmailclient.sourceforge.net

(первое на utl_smtp, последнее через JavaMail)
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #38027352
Фотография May12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chameleon82, спасибо. почитала, но не уловила.
Может Ваш пакет отправлять таблицы в теле письма?
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #38027576
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Какие именно таблицы? Не совсем понятно, о чем идет речь. Если о таблицах БД - то, разумеется, пакет для этого и создавался. Формат данных Вы должны подготовить сами. В принципе, пакет может отправлять все что угодно, Вам необходимо только подготовить необходимые данные в файл или в клоб и вложить в апи. Я лично без проблем отправляю через пакет генерируемые в pl/sql xml-excel файлы (несколько штук по 10-15 мегабайт каждое в одном письме) плюс из файловой системы подтягиваю логотип для подписи в письме. Если Вам необходимо архивировать, то сначала сохраните данные в файл, затем заархивируйте (решения можно поискать на форуме) и потом приложите в пакет.
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #38027599
chameleon82
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-может быть сейчас с этим получше, во времена outlook express проблем хватало, особенно с переадресованными между разными почтовыми клиентами писем. проблемой было даже понять, что из миме-партийцев является телом самого сообщения.


Главная цель, для которой был написан прием почты - возможность скармливать ораклу массивы данных. В принципе, найти в партициях то, что нужно зная что искать - не самая сложная задача )
На моем примере это массовая обработка транзакций ) почтовый сервер хорошо логгирует историю действий ленивых бухгалтеров ) Допустим, мы выгрузили массив данных в 1000 транзакций (в екселе бухам намного проще почему-то делать это), затем бухгалтер отправляет файл на почту ораклу, задав специальный заголовок, оракл получил письмо, обработал, выслал на обратный адрес результат загрузки с указанием ошибок. Ну вот сложно бухам через форму прикладывать файл или грузить через фтп )
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #38028223
Фотография May12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chameleon82,

имелось в виду небольшие таблицы-отчеты в теле письма (используя html и css). Я эту проблему тут озвучила и меня направили сюда.
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #38030900
seregaLOKI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я при помощи данного пакета реализовал отправку таблиц в виде html размером по несколько метров
...
Рейтинг: 0 / 0
Передача письма с вложением. Готовое решение
    #38034059
seregaLOKI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хотел поинтересоваться есть ли следующая возможность:

Выбираем нужные данные и их отправляем формате xls в качестве аттача с присваиванием ему имени, как я понял у вас реализовано присоединение файлов которые где то у нас хранятся заранее?
...
Рейтинг: 0 / 0
25 сообщений из 274, страница 4 из 11
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Передача письма с вложением. Готовое решение
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]