Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7 8 9 10 11   вперед  Ctrl      все
 Передача письма с вложением. Готовое решение  [new]
chameleon82
Member

Откуда: Russia, Новосибирск
Сообщений: 251
В долгих поисках рабочего решения так и не смог найти ничего ценного.
Пришлось почитать RFC и написать свое. Надеюсь кому-нибудь пригодится.
Пакет позволяет добавлять несколько вложений, что немаловажно - так это включая бинарники.
Возможно, кто-нибудь в благодарность поможет мне усовершенствовать пакет такими вещами как авторизация, или оптимизация. Пользуйтесь ;)

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
-- --------------------------------------------------------------------------

/* EXAMPLE:

    BEGIN
	 MAIL_PKG.ADD_ATTACHMENT( 'ODPDIR'
							 ,'picture.gif'
							 ,'image/gif'
							);
	 MAIL_PKG.SEND( mailto => 'a.nekrasov@yourserver.ru'
	              , subject => 'Test subject'
				  , message => 'Some <b>bold</b> message!'
				  , mailfrom => 'no-reply@yourserver.ru'
                  , mimetype => 'text/html'
				  , sendername => 'Alert system'
				  , recipientname => 'Dear user'
	              );
	END;
*/

 -- 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
                          );						  
						   						  
 -- 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 'B') RETURN VARCHAR2;

 -- PREPARE
 --  Prepare configs for email. 
 PROCEDURE PREPARE;				
				
 -- ADD_ATTACHMENT
 --  Add 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
                           );
 -- SEND
 --  Send email with attachments to recipient
 -- IN
 -- MAILTO is email address of recipient
 -- SUBJECT is subject of email
 -- MESSAGE is message of email
 -- MIMETYPE is mime-type of message. Available values is 'text/plain' and 'text/html'
 -- SENDERNAME is mail-sender name
 -- RECIPIENTNAME is name of recipient 
 PROCEDURE SEND ( mailto IN VARCHAR2
				, subject IN VARCHAR2
				, message IN VARCHAR2
                , mailfrom IN VARCHAR2
				, mimetype IN VARCHAR2 DEFAULT 'text/plain'
				, sendername IN VARCHAR2 DEFAULT NULL
				, recipientname IN VARCHAR2 DEFAULT NULL
                );
END MAIL_PKG;
/
CREATE OR REPLACE PACKAGE BODY MAIL_PKG
IS

 mailserver VARCHAR2(30):='localhost';
 mailport INTEGER:=25;
 type attach_row is record ( dirname varchar2(30)
                           , filename  varchar2(30)
                           , name  varchar2(30)
						   , mimetype varchar2(30)
                           );
 type attach_list is table of attach_row;
 attachments attach_list;
 PROCEDURE SET_MAILSERVER ( mailserver varchar2
                          , mailport number default 25
                          ) IS
 BEGIN
  MAIL_PKG.mailserver := mailserver;
  MAIL_PKG.mailport := mailport;
 END;
 
 FUNCTION ENCODE(str IN VARCHAR2, tp IN VARCHAR2 DEFAULT 'B') RETURN VARCHAR2 IS
 BEGIN
   IF tp='B' THEN
     RETURN '=?windows-1251?B?'|| UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw (CONVERT (str, 'CL8MSWIN1251'))))|| '?=';
   ELSE
     RETURN str;
   END IF;
 END;

 PROCEDURE PREPARE
 IS
 BEGIN
   MAIL_PKG.attachments:=MAIL_PKG.attach_list(); 
 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;
   ELSE
      RAISE_APPLICATION_ERROR(-20001, 'File is not exists');
   END IF;
 END;


 PROCEDURE SEND ( mailto IN VARCHAR2
				, subject IN VARCHAR2
				, message IN VARCHAR2
                , mailfrom IN VARCHAR2
				, mimetype IN VARCHAR2 DEFAULT 'text/plain'
				, sendername IN VARCHAR2 DEFAULT NULL
				, recipientname IN VARCHAR2 DEFAULT NULL								
                )
 IS
   v_Mail_Conn  utl_smtp.Connection;
   crlf         VARCHAR2(2)  := utl_tcp.CRLF; -- chr(13)||chr(10);
   boundary VARCHAR2(50) := '-----7D81B75CCC90DFRW4F7A1CBD';
   vFile BFILE;
   vRAW RAW(32767);
   amt CONSTANT BINARY_INTEGER := 48; -- 48bytes binary convert to 128bytes of base64.
   v_amt BINARY_INTEGER;
   ps BINARY_INTEGER := 1;
   v_mime VARCHAR2(30);
 BEGIN
    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);
    utl_smtp.Helo(v_Mail_Conn,MAIL_PKG.mailserver);
    utl_smtp.Mail(v_Mail_Conn, mailfrom);
    utl_smtp.Rcpt(v_Mail_Conn, mailto);

    utl_smtp.open_data(v_Mail_Conn); -- open data sheet

	utl_smtp.write_data(v_Mail_Conn, 'Date: ' || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf);
    utl_smtp.write_data(v_Mail_Conn, 'From: ');
    utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(sendername));	
    utl_smtp.write_data(v_Mail_Conn, ' <'||mailfrom ||'>' || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Subject: '|| MAIL_PKG.ENCODE(subject) || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'To: ');
    utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(recipientname));
    utl_smtp.write_data(v_Mail_Conn, ' <'||mailto ||'>' || crlf );

    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
    utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||v_mime||'; charset="Windows-1251"'|| 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(message));
    utl_smtp.write_data(v_Mail_Conn, crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );

	--Attachments
	IF MAIL_PKG.attachments is not null THEN
	  FOR x IN 1 .. MAIL_PKG.attachments.count LOOP
          utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
          utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||MAIL_PKG.attachments(x).mimetype||';'|| crlf );
          utl_smtp.write_data(v_Mail_Conn, ' name="'||MAIL_PKG.attachments(x).name||'"'|| 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.attachments(x).name||'"' || crlf);
          utl_smtp.write_data(v_Mail_Conn, crlf );
		  dbms_output.put_line(MAIL_PKG.attachments(x).dirname);
		  dbms_output.put_line(MAIL_PKG.attachments(x).filename);		  
		  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);

          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.quit(v_Mail_Conn);
	   EXCEPTION WHEN OTHERS THEN NULL;
	   END;
	RAISE;	
 END;

BEGIN
  MAIL_PKG.attachments:=MAIL_PKG.attach_list();
END;
/

22 янв 10, 19:53    [8232242]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
chameleon82
Member

Откуда: Russia, Новосибирск
Сообщений: 251
Доработал пакет, убрал лишнее, сделал разбор входящих емайлов (можно отправлять на несколько емайлов), добавил приоритет письма, добавил авторизацию. Сделал необязательным адрес отправителя (по умолчанию mail@имя_сервера).

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
-- --------------------------------------------------------------------------

/* EXAMPLE:

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

 2) Extension Email with attacments
  	
    BEGIN
	 MAIL_PKG.SET_MAILSERVER ('localhost',25);
	 MAIL_PKG.SET_AUTH ('username','password');	
	 MAIL_PKG.ADD_ATTACHMENT( 'ODPDIR','image.jpeg','image/jpeg');
	 MAIL_PKG.ADD_ATTACHMENT( 'ODPDIR','picture.gif','image/gif');
	 MAIL_PKG.SEND( mailto => 'User1 <user1@domain.ru>, User2 <user2@domain.ru>'
	             , subject => 'Test subject'
	             , message => 'Some <b>bold</b> message!'
		     , mailfrom => 'Oracle Notify <no-reply@s7.ru>'
                      , mimetype => 'text/html'
                      , priority => 1
	              );
  END;
*/

 -- 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 'B') RETURN VARCHAR2;

 -- PREPARE
 --  Prepare configs for email. 
 PROCEDURE PREPARE;				
				
 -- ADD_ATTACHMENT
 --  Add 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
                           );
 -- 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 VARCHAR2
                , 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);
 type attach_row is record ( dirname varchar2(30)
                           , filename  varchar2(30)
                           , name  varchar2(30)
						   , mimetype varchar2(30)
                           );
 type attach_list is table of attach_row;
 attachments attach_list;
 
 type rcpt_row is record ( rcptname varchar2(50)
                     , rcptmail varchar2(30)
					 );
 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 'B') RETURN VARCHAR2 IS
 BEGIN
   IF tp='B' THEN
     RETURN '=?windows-1251?B?'|| UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(UTL_RAW.cast_to_raw (CONVERT (str, 'CL8MSWIN1251'))))|| '?=';
   ELSE
     RETURN str;
   END IF;
 END;

 PROCEDURE PREPARE
 IS
 BEGIN
   MAIL_PKG.attachments:=MAIL_PKG.attach_list(); 
 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;
   ELSE
      RAISE_APPLICATION_ERROR(-20001, 'File is not exists');
   END IF;
 END;

 FUNCTION CREATE_RCPT_LIST(mailto IN VARCHAR2) RETURN MAIL_PKG.rcpt_list IS
  v_mailto VARCHAR2(4096) := replace(mailto,';',',')||',';
  pntr INTEGER;
  buf VARCHAR2(50);
  rcptmail VARCHAR2(30);
  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 := 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:= 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 VARCHAR2
                , mailfrom IN VARCHAR2 DEFAULT NULL
				, mimetype IN VARCHAR2 DEFAULT 'text/plain'
				, priority IN NUMBER DEFAULT NULL												
                )
 IS
   v_Mail_Conn  utl_smtp.Connection;
   crlf         VARCHAR2(2)  := utl_tcp.CRLF; -- chr(13)||chr(10);
   boundary VARCHAR2(50) := '-----7D81B75CCC90DFRW4F7A1CBD';
   vFile BFILE;
   vRAW RAW(32767);
   amt CONSTANT BINARY_INTEGER := 48; -- 48bytes binary convert to 128bytes of base64.
   v_amt BINARY_INTEGER;
   ps BINARY_INTEGER := 1;
   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))));    		 
		 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(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf);
    utl_smtp.write_data(v_Mail_Conn, 'From: ');
    utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(sndr.rcptname));	
    utl_smtp.write_data(v_Mail_Conn, ' <'||sndr.rcptmail ||'>' || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Subject: '|| MAIL_PKG.ENCODE(subject) || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'To: ');
    utl_smtp.write_raw_data(v_Mail_Conn, utl_raw.cast_to_raw(mailto));
    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
    utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
    utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||v_mime||'; charset="Windows-1251"'|| 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(message));
    utl_smtp.write_data(v_Mail_Conn, crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );

	--Attachments
	IF MAIL_PKG.attachments is not null THEN
	  FOR x IN 1 .. MAIL_PKG.attachments.count LOOP
          utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
          utl_smtp.write_data(v_Mail_Conn, 'Content-Type: '||MAIL_PKG.attachments(x).mimetype||';'|| crlf );
          utl_smtp.write_data(v_Mail_Conn, ' name="'||MAIL_PKG.attachments(x).name||'"'|| 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.attachments(x).name||'"' || crlf);
          utl_smtp.write_data(v_Mail_Conn, crlf );		  
		  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);

          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;
/

24 янв 10, 09:32    [8235643]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
comphead
Member

Откуда: Киев
Сообщений: 3390
chameleon82,

спс )
2 мар 10, 11:23    [8416800]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
tesaq
Member

Откуда:
Сообщений: 2
это ох какое спсб
------------- свЕдение данных в таблицу уже есть СЕКРЕТНО ---
2 мар 10, 11:34    [8416888]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
comphead
Member

Откуда: Киев
Сообщений: 3390
chameleon82,

Кстати, в пакете решена проблема того что тело сообщения в UTL_SMTP должно быть не больше 32K?
9 мар 10, 17:38    [8451163]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
chameleon82
Member

Откуда: Russia, Новосибирск
Сообщений: 251
comphead
chameleon82,

Кстати, в пакете решена проблема того что тело сообщения в UTL_SMTP должно быть не больше 32K?


Кстати не проверял ) Я тут еще подладил пакет на длинные названия в заголовке. Проверю, если что исправлю, обновлю пост :)
1 апр 10, 12:13    [8564257]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
Ura!
Member

Откуда:
Сообщений: 273
Правильно понимаю, что файлы для атачментов должны лежать на сервере?
И ещё вопрос, цифровой подписью не баловались? т.е. перед отправкой письма подписать его цифровой подписью.
1 апр 10, 14:54    [8565912]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
chameleon82
Member

Откуда: Russia, Новосибирск
Сообщений: 251
Ura!
Правильно понимаю, что файлы для атачментов должны лежать на сервере?
И ещё вопрос, цифровой подписью не баловались? т.е. перед отправкой письма подписать его цифровой подписью.

Да. Файлы должны быть на сервере в одной из директорий select * from all_directories, туда их при необходимости можно скопировать.
Размер и количество отправляемых файлов неограничены (ну по крайней мере можно отправить сразу несколько картинок по несколько мегабайт или несколько больших отчетов одновременно).
Цифровая подпись, это чтото интересное. Сомневаюсь, что здесь такое возможно, т.к. письмо отдается смтп серверу последовательно (хотя если его сначала сохранить в blob, то может и получится). Хотя если сможете доработать пакет, было бы интересно посмотреть на реализацию :)
6 апр 10, 08:22    [8583246]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
aure
Member

Откуда:
Сообщений: 9
chameleon82
В долгих поисках рабочего решения так и не смог найти ничего ценного.
Пришлось почитать RFC и написать свое. Надеюсь кому-нибудь пригодится.
Пакет позволяет добавлять несколько вложений, что немаловажно - так это включая бинарники.
Возможно, кто-нибудь в благодарность поможет мне усовершенствовать пакет такими вещами как авторизация, или оптимизация. Пользуйтесь ;)
[/src]


Спасибо! ;)
21 май 10, 10:45    [8811723]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
d.nemolchev
Member

Откуда: Кустанай
Сообщений: 291
chameleon82,

а JavaMail чем Вас не устроил?
22 май 10, 13:37    [8818119]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
d.nemolchev
Member

Откуда: Кустанай
Сообщений: 291
PS Сразу с PL/SQL-оберткой
22 май 10, 13:45    [8818123]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 15757
Сразу можно отметить, что хардкодить в такие пакеты ansi1251 - не очень разумная идея.
Даже если Вы не верите что Ваше детище пригодится кому-нибудь в просвещенной Европе, то подумйте хотя бы о мультиязычных текстах в рамках таможенного союза :)
22 май 10, 15:19    [8818339]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
IgorD
Member

Откуда: Киев
Сообщений: 220
chameleon82 - СПАСИБО!

Внес незначительные изменение в авторизацию в фрагменте кода, добавив exit
    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;	


В моем случае в replies(x).text фраза 'AUTH' встречалась дважды, что вызывало ошибку при повторной авторизации. Еще планирую добавить к пакету таблицу лог, в которой писать отправлено/не отравлено сообщение, когда и т.п. Нужно для автоматической работы в джобах и т.п.
25 май 10, 16:26    [8831651]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
dba123
Member

Откуда:
Сообщений: 915
chameleon82,

еще предложение

менять имена границ подразделов(boundary), например

S7RUMailPart-001-xxxxxxxx-xxxxxxxxxxxxxxxxx
S7RUMailPart-002-xxxxxxxx-xxxxxxxxxxxxxxxxx

где ххх может быть счетчиком, уникальным идентификатором, цифровой сверткой/подписью и т.д.
и тебе учет отправленных и сормовцам метки :)
25 май 10, 16:56    [8831964]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
chameleon82
Member

Откуда: Russia, Новосибирск
Сообщений: 251
d.nemolchev
chameleon82,

а JavaMail чем Вас не устроил?

Хотелось чисто PL/SQL-ное решение, тем более оно не такое сложное. Да и если следовать словам Томаса Кайта - "зачем использовать java, если можно сделать на pl/sql?". Единтсвтенное пока, что тут может пригодиться из java при отправке письма - это архивирование вложений (но это можно сделать и другими средствами).


andrey_anonymous
Сразу можно отметить, что хардкодить в такие пакеты ansi1251 - не очень разумная идея.
Даже если Вы не верите что Ваше детище пригодится кому-нибудь в просвещенной Европе, то подумйте хотя бы о мультиязычных текстах в рамках таможенного союза :)


пакет собран на коленке ))) надо проработать этот вопрос

IgorD
chameleon82 - СПАСИБО!

Внес незначительные изменение в авторизацию в фрагменте кода, добавив exit

И вам спасибо ;)

dba123
chameleon82,

еще предложение - менять имена границ подразделов(boundary)
26 май 10, 07:54    [8834002]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
chameleon82
Member

Откуда: Russia, Новосибирск
Сообщений: 251
dba123
chameleon82,

еще предложение

менять имена границ подразделов(boundary), например

S7RUMailPart-001-xxxxxxxx-xxxxxxxxxxxxxxxxx
S7RUMailPart-002-xxxxxxxx-xxxxxxxxxxxxxxxxx

где ххх может быть счетчиком, уникальным идентификатором, цифровой сверткой/подписью и т.д.
и тебе учет отправленных и сормовцам метки :)


надо обдумать как это сделать. идея интересная. Думаю, можно внедрить допнастройками пакета. А вот где хранить счетчик? создавать ради этого сиквенс???

---

Обновил пакет. Убрал немного мусора, перевел все на UTF-8 (протестил на бате и аутлуке), исправил ошибку с длинным именем заголовка письма и именами отправителей/получателей и что-то еще по мелочи, и замечание от IgorD. Вот моя последняя версия )

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
-- --------------------------------------------------------------------------

/* EXAMPLE:

 1) Short text email

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

 2) Extension Email with attacments

    BEGIN
	 MAIL_PKG.SET_MAILSERVER ('localhost',25);
	 MAIL_PKG.SET_AUTH ('a.nekrasov','password');
	 MAIL_PKG.ADD_ATTACHMENT( 'ODPDIR'
							 ,'girl3d.jpeg'
							 ,'image/jpeg'
							);
	 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;
*/

 -- 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 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
                           );
 -- 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 VARCHAR2
                , 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)
                           );
 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
   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;
   ELSE
      RAISE_APPLICATION_ERROR(-20001, 'File is not exists');
   END IF;
 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 VARCHAR2
                , 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 := 48; -- 48bytes binary convert to 128bytes of base64.
   v_amt BINARY_INTEGER;
   ps BINARY_INTEGER := 1;
   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
	     dbms_output.put_line(replies(x).text);
 	     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(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss','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
    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')));
    utl_smtp.write_data(v_Mail_Conn, crlf );
    utl_smtp.write_data(v_Mail_Conn, crlf );

	--Attachments
	IF MAIL_PKG.attachments is not null THEN
	  FOR x IN 1 .. MAIL_PKG.attachments.count LOOP
          utl_smtp.write_data(v_Mail_Conn, '--'|| boundary || crlf );
          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);
          utl_smtp.write_data(v_Mail_Conn, crlf );
		  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);

          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;
/
26 май 10, 08:17    [8834046]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
_Ildar_
Member

Откуда: Astrakhan
Сообщений: 306
Очень интересное решение.
У меня размер сообщения больше 32Кб?

Как отправить такое сообщение?

Спасибо!
7 июн 10, 19:57    [8904812]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
вопросец
Guest
у меня всегда возникает вопрос. зачем тулить этот левый функцианал. и каким то диким извратом его реализовывать. не лучше ли потратив гораздо меньше времени по быренькому склепать службу/демон или задание шедулера/крона которое выколупает из БД необходимые данные и разошлет там чего-то. тем более что такие рассыльщики имеют свойство расползаться до монстров с тяжелой логикой.
7 июн 10, 20:13    [8904849]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
SQL*Plus
Member

Откуда: Россия, Москва
Сообщений: 7726
вопросец
у меня всегда возникает вопрос. зачем тулить этот левый функцианал. и каким то диким извратом его реализовывать. не лучше ли потратив гораздо меньше времени по быренькому склепать службу/демон или задание шедулера/крона которое выколупает из БД необходимые данные и разошлет там чего-то. тем более что такие рассыльщики имеют свойство расползаться до монстров с тяжелой логикой.
Это не "левый функционал".
Это нормальный подход программиста Oracle Database использовать штатные возможности Oracle Database.
Для этого требуется только хорошее знание PL/SQL и предлагаемых для него штатных пакетов.

Не требуются знания:
- как "по быренькому склепать службу/демон или задание шедулера/крона"
- как "выколупать из БД необходимые данные" во внешние файлы/места
- как реализовать вне БД "монстров с тяжелой логикой"
То есть не требуется никакого "дикого изврата", внешнего по отношению к БД.

Знаешь PL/SQL - пользуйся им. PL/SQL хватает практически для всего.
7 июн 10, 20:28    [8904875]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
_Ildar_
Member

Откуда: Astrakhan
Сообщений: 306
вопросец
у меня всегда возникает вопрос. зачем тулить этот левый функцианал. и каким то диким извратом его реализовывать. не лучше ли потратив гораздо меньше времени по быренькому склепать службу/демон или задание шедулера/крона которое выколупает из БД необходимые данные и разошлет там чего-то. тем более что такие рассыльщики имеют свойство расползаться до монстров с тяжелой логикой.


Вот есть несколько прог, которые запускаюся по расписанию на серваке x86 9.2.0.7
Сейчас переехал на сервак 10.2.0.4. по x64 и проги на 32 разряда не работают из-за:
Ошибка: В указанном DSN архитектура драйвера и архитектура приложения не соответствуют друг другу.
Проги x86 не хотят коннектиться к БД с помощью ODBC x64 драйвера оракла.
Если бы все было сделано средствами оракла проблем при переходе небыло.
Для меня, что одна из полезностей этого пакета именно в этом.
Переписывать под x64 конечно можно, но проц у меня не понимает такие ОС.
Пакет полезный, но тело сообщения ограничено 32 К !!!

HELP!!!! Помогите!
7 июн 10, 20:39    [8904896]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
вопросец
Guest
_Ildar_,

чтобы x86_32 прога жила под x86_64 нужен клиент x86_32

а почему же вы не протестировали работоспособность ПО прежде чем осуществлять переход? я так понимаю это продакшн. прога может упасть н только из-за того что не может в свое 32-bit адрасное пространство грузить x86_64 модули :). но может и повезти.

---

впринципе мысльвысказавшихся я понял.
7 июн 10, 20:47    [8904911]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
_Ildar_
Member

Откуда: Astrakhan
Сообщений: 306
вопросец
_Ildar_,
чтобы x86_32 прога жила под x86_64 нужен клиент x86_32

Да. Нужен, то не устанавливается клиент x86 на x64 платформу! Хоть ты тресни!

вопросец

а почему же вы не протестировали работоспособность ПО прежде чем осуществлять переход? я так понимаю это продакшн. прога может упасть н только из-за того что не может в свое 32-bit адрасное пространство грузить x86_64 модули :). но может и повезти.

Не повезло. От такого невезения и ищу решение.
Обойти бы это ограничение по размеру тела письма и все было бы ОК!
7 июн 10, 21:02    [8904951]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
вопросец
Guest
_Ildar_,

не правда ваша. клиент x86_32 работает под x86_64. (Oracle Client)
7 июн 10, 21:35    [8905015]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 15757
_Ildar_
Обойти бы это ограничение по размеру тела письма и все было бы ОК!

Шлите письма html-аттачем, как поступают все современные спамеры :)
7 июн 10, 21:37    [8905022]     Ответить | Цитировать Сообщить модератору
 Re: Передача письма с вложением. Готовое решение  [new]
_Ildar_
Member

Откуда: Astrakhan
Сообщений: 306
andrey_anonymous
_Ildar_
Обойти бы это ограничение по размеру тела письма и все было бы ОК!

Шлите письма html-аттачем, как поступают все современные спамеры :)

Это мысль. Надо попробовать.
8 июн 10, 13:01    [8907625]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3 4 5 6 7 8 9 10 11   вперед  Ctrl      все
Все форумы / Oracle Ответить