CftClub.ru
Клуб специалистов ЦФТ-Банк

Рассылка сообщений на e-mail
На страницу Пред.  1, 2, 3  След.
 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы
Предыдущая тема :: Следующая тема  
Автор Сообщение
dnk_dz
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеЧт Фев 14, 2008 07:22    Ответить с цитатой
Полезность: 1
timochev пишет:
ssa774 пишет:
И еще не отправляет на два адреса сразу. Пробовала и через ";" и через "," - не работает...

Мы смогли только написать свою функцию, которая разбирает строку адресатов и отправляет письмо каждому по-очереди.


Чтобы отравить письмо нескольким получателям необходимо
доработать процедуру следующим образом: разобрать строку переданных адресов получателей и для каждого адреса вызвать.

Код:
utl_smtp.rcpt(v_connection,p_to);
ssa774
Профи


Вступление в Клуб: 30.11.2007
СообщениеЧт Фев 14, 2008 11:12    Ответить с цитатой
Полезность: 2
Тема письма на русском - используем CONVERT.
Вот так у меня работает:

Код
Код:
Send_Mail(host,port,from,to,utl_raw.cast_to_raw(convert(subject,'CL8KOI8R')),utl_raw.cast_to_raw(data));
Admin
Site Admin


Вступление в Клуб: 09.06.2007
СообщениеПт Фев 15, 2008 11:35   Re: Рассылка сообщений на e-mail Ответить с цитатой
Полезность: Нет оценки
w00per пишет:
Может дело не в ЦФТшных операциях, а в настройке почтового сервера. Например SMTP требует авторизации или еще что-то типа того, попробуйте посмотреть в эту сторону.


Можно ли настроить отправку почты, если SMTP требует авторизации ?
dnk_dz
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеПт Фев 15, 2008 12:10   Re: Рассылка сообщений на e-mail Ответить с цитатой
Полезность: 1
Admin пишет:

Можно ли настроить отправку почты, если SMTP требует авторизации ?


Можно. Попробуйте так:
Код:
...
v_connection:=utl_smtp.open_connection(p_host,p_port);
-- Авторизация
utl_smtp.command( v_connection, 'AUTH LOGIN');
utl_smtp.command(v_connection, utl_raw.cast_to_varchar2( utl_encode.base64_encode( utl_raw.cast_to_raw(MailUserName))) );
utl_smtp.command( v_connection, utl_raw.cast_to_varchar2( utl_encode.base64_encode( utl_raw.cast_to_raw(MailPassword ))) );

utl_smtp.helo(v_connection,'domain.ru');
...
ssa774
Профи


Вступление в Клуб: 30.11.2007
СообщениеПт Фев 15, 2008 12:15   Re: Рассылка сообщений на e-mail Ответить с цитатой
Полезность: 1
Admin пишет:
w00per пишет:
Может дело не в ЦФТшных операциях, а в настройке почтового сервера. Например SMTP требует авторизации или еще что-то типа того, попробуйте посмотреть в эту сторону.


Можно ли настроить отправку почты, если SMTP требует авторизации ?


Если есть пароль и пользователь, то, возможно, поможет вот такая процедура
Код:
  procedure auth_mail(conn IN OUT NOCOPY utl_smtp.connection, smtp_user in varchar2, smtp_password in varchar2) is
  begin   
    utl_smtp.command(conn, 'AUTH LOGIN');
    utl_smtp.command(conn,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(smtp_user))));
    utl_smtp.command(conn,utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(smtp_password))));   
  end;


Вызывается после открытия соединения и настройки сеанса

Код:
   v_connection:=utl_smtp.open_connection(p_host,p_port);
   utl_smtp.helo(v_connection,'domain.ru');
   utl_smtp.mail(v_connection,'oracle-server@domain.ru');
   auth_mail(v_connection, smtp_user, smtp_password);
Admin
Site Admin


Вступление в Клуб: 09.06.2007
СообщениеПт Фев 15, 2008 12:36   Re: Рассылка сообщений на e-mail Ответить с цитатой
Полезность: Нет оценки
dnk_dz пишет:
Можно. Попробуйте так:
Код:
...
v_connection:=utl_smtp.open_connection(p_host,p_port);
-- Авторизация
utl_smtp.command( v_connection, 'AUTH LOGIN');
utl_smtp.command(v_connection, utl_raw.cast_to_varchar2( utl_encode.base64_encode( utl_raw.cast_to_raw(MailUserName))) );
utl_smtp.command( v_connection, utl_raw.cast_to_varchar2( utl_encode.base64_encode( utl_raw.cast_to_raw(MailPassword ))) );

utl_smtp.helo(v_connection,'domain.ru');
...


Светлана, Дмитрий, спасибо, работает!

Дмитрий, единственное дополнение - строка utl_smtp.helo(v_connection,'domain.ru'); должна стоять ДО блока авторизации (у Светланы правильно).
dnk_dz
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеПт Фев 15, 2008 14:49   Re: Рассылка сообщений на e-mail Ответить с цитатой
Полезность: Нет оценки
Admin пишет:
Дмитрий, единственное дополнение - строка utl_smtp.helo(v_connection,'domain.ru'); должна стоять ДО блока авторизации (у Светланы правильно).

Извините, не досмотрел Very Happy
SkyLynx
Участник


Вступление в Клуб: 30.06.2007
СообщениеПн Апр 28, 2008 06:02    Ответить с цитатой
Полезность: 2
недавно писал отправку электронных сообщений из pl/sql для одной системы, позже запихнул в ЦФТешную схему.
Ниже привожу получившийся код для критики и предложений Wink
Код:

create or replace package body UTL_SMTP$ is

FUNCTION get_address(addr_list IN OUT VARCHAR2) RETURN VARCHAR2 IS
   addr VARCHAR2(256);
   i    pls_integer;

   FUNCTION lookup_unquoted_char(
      str  IN VARCHAR2,
      chrs IN VARCHAR2
   ) RETURN pls_integer AS
      c            VARCHAR2(5);
      i            pls_integer;
      len          pls_integer;
      inside_quote BOOLEAN;
   BEGIN
      inside_quote := false;
      i := 1;
      len := length(str);
      WHILE (i <= len) LOOP
         c := substr(str, i, 1);
         IF (inside_quote) THEN
            IF (c = '"') THEN
               inside_quote := false;
            ELSIF (c = '\') THEN
               i := i + 1; -- Skip the quote character
            END IF;
            GOTO next_char;
         END IF;
         IF (c = '"') THEN
            inside_quote := true;
            GOTO next_char;
         END IF;
         IF (instr(chrs, c) >= 1) THEN
            RETURN i;
         END IF;
         <<next_char>>
         i := i + 1;
      END LOOP;
      RETURN 0;
   END;

BEGIN
   addr_list := ltrim(addr_list);
   i := lookup_unquoted_char(addr_list, ',;');
   IF (i >= 1) THEN
      addr      := substr(addr_list, 1, i - 1);
      addr_list := substr(addr_list, i + 1);
   ELSE
      addr := addr_list;
      addr_list := '';
   END IF;
   
   i := lookup_unquoted_char(addr, '<');
   IF (i >= 1) THEN
      addr := substr(addr, i + 1);
      i := instr(addr, '>');
      IF (i >= 1) THEN
         addr := substr(addr, 1, i - 1);
      END IF;
   END IF;
   RETURN addr;
END;

PROCEDURE write_mime_header(
   conn  IN OUT NOCOPY utl_smtp.connection,
   name  IN VARCHAR2,
   value IN VARCHAR2
) IS
BEGIN
   if mail_charset is not null then
      utl_smtp.write_raw_data(conn, utl_raw.cast_to_raw(convert(name || ': ' || value || utl_tcp.CRLF,mail_charset)));
   else
      utl_smtp.write_data(conn, name || ': ' || value || utl_tcp.CRLF);
   end if;
END;

boundary.
PROCEDURE write_boundary(
   conn  IN OUT NOCOPY utl_smtp.connection,
   last  IN            BOOLEAN DEFAULT FALSE
) AS
BEGIN
   IF (last) THEN
      utl_smtp.write_data(conn, LAST_BOUNDARY);
   ELSE
      utl_smtp.write_data(conn, FIRST_BOUNDARY);
   END IF;
END;

------------------------------------------------------------------------
PROCEDURE mail(
   sender     IN VARCHAR2,
   recipients IN VARCHAR2,
   subject    IN VARCHAR2,
   message    IN VARCHAR2,
   mime_type  IN VARCHAR2 default 'text/plain'
) IS
   conn utl_smtp.connection;
BEGIN
   conn := begin_mail(sender, recipients, subject, mime_type);
   write_text(conn, message);
   end_mail(conn);
END;

------------------------------------------------------------------------
FUNCTION begin_mail(
   sender     IN VARCHAR2,
   recipients IN VARCHAR2,
   subject    IN VARCHAR2,
   mime_type  IN VARCHAR2    DEFAULT 'text/plain',
   priority   IN PLS_INTEGER DEFAULT NULL
) RETURN utl_smtp.connection IS
   conn utl_smtp.connection;
BEGIN
   if smtp_port is null then
      smtp_port:=25;
   end if;
   if smtp_domain is null then   
      if instr(smtp_host,'.')>0 then
         smtp_domain:=substr(smtp_host,instr(smtp_host,'.')+1);
      end if;
   end if;
   if instr(upper(mime_type),'CHARSET')>0 then
      if instr(upper(mime_type),'WINDOWS-1251')>0 then
         mail_charset:='CL8MSWIN1251';
      end if;
   end if;
   conn := begin_session;
   begin_mail_in_session(conn, sender, recipients, subject, mime_type, priority);
   RETURN conn;
END;

------------------------------------------------------------------------
PROCEDURE write_text(
   conn    IN OUT NOCOPY utl_smtp.connection,
   message IN VARCHAR2
) IS
BEGIN
   if mail_charset is not null then
      utl_smtp.write_raw_data(conn, utl_raw.cast_to_raw(convert(message,mail_charset)));
   else
      utl_smtp.write_data(conn, message);
   end if;
END;

------------------------------------------------------------------------
PROCEDURE write_mb_text(
   conn    IN OUT NOCOPY utl_smtp.connection,
   message IN            VARCHAR2
) IS
BEGIN
   if mail_charset is not null then
      utl_smtp.write_raw_data(conn, utl_raw.cast_to_raw(convert(message,mail_charset)));
   else
      utl_smtp.write_raw_data(conn, utl_raw.cast_to_raw(message));
   end if;
END;

------------------------------------------------------------------------
PROCEDURE write_raw(
   conn    IN OUT NOCOPY utl_smtp.connection,
   message IN RAW
) IS
BEGIN
   utl_smtp.write_raw_data(conn, message);
END;

------------------------------------------------------------------------
PROCEDURE attach_text(
   conn         IN OUT NOCOPY utl_smtp.connection,
   data         IN VARCHAR2,
   mime_type    IN VARCHAR2 DEFAULT 'text/plain',
   inline       IN BOOLEAN  DEFAULT TRUE,
   filename     IN VARCHAR2 DEFAULT NULL,
   last         IN BOOLEAN  DEFAULT FALSE
) IS
BEGIN
   begin_attachment(conn, mime_type, inline, filename);
   write_text(conn, data);
   end_attachment(conn, last);
END;

------------------------------------------------------------------------
PROCEDURE attach_base64(
   conn         IN OUT NOCOPY utl_smtp.connection,
   data         IN RAW,
   mime_type    IN VARCHAR2 DEFAULT 'application/octet',
   inline       IN BOOLEAN  DEFAULT TRUE,
   filename     IN VARCHAR2 DEFAULT NULL,
   last         IN BOOLEAN  DEFAULT FALSE
) IS
   i   PLS_INTEGER;
   len PLS_INTEGER;
BEGIN
   begin_attachment(conn, mime_type, inline, filename, 'base64');
   -- Split the Base64-encoded attachment into multiple lines
   i   := 1;
   len := utl_raw.length(data);
   WHILE (i < len) LOOP
      IF (i + MAX_BASE64_LINE_WIDTH < len) THEN
         utl_smtp.write_raw_data(conn,
         utl_encode.base64_encode(utl_raw.substr(data, i, MAX_BASE64_LINE_WIDTH)));
      ELSE
         utl_smtp.write_raw_data(conn,
         utl_encode.base64_encode(utl_raw.substr(data, i)));
      END IF;
      utl_smtp.write_data(conn, utl_tcp.CRLF);
      i := i + MAX_BASE64_LINE_WIDTH;
   END LOOP;
   end_attachment(conn, last);
END;

------------------------------------------------------------------------
PROCEDURE begin_attachment(
   conn         IN OUT NOCOPY utl_smtp.connection,
   mime_type    IN VARCHAR2 DEFAULT 'text/plain',
   inline       IN BOOLEAN  DEFAULT TRUE,
   filename     IN VARCHAR2 DEFAULT NULL,
   transfer_enc IN VARCHAR2 DEFAULT NULL) IS
BEGIN
   write_boundary(conn);
   write_mime_header(conn, 'Content-Type', mime_type);

   IF (filename IS NOT NULL) THEN
      IF (inline) THEN
         write_mime_header(conn, 'Content-Disposition','inline; filename="'||filename||'"');
      ELSE
         write_mime_header(conn, 'Content-Disposition','attachment; filename="'||filename||'"');
      END IF;
   END IF;

   IF (transfer_enc IS NOT NULL) THEN
      write_mime_header(conn, 'Content-Transfer-Encoding', transfer_enc);
   END IF;
   utl_smtp.write_data(conn, utl_tcp.CRLF);
END;

------------------------------------------------------------------------
PROCEDURE end_attachment(
   conn IN OUT NOCOPY utl_smtp.connection,
   last IN BOOLEAN DEFAULT FALSE
) IS
BEGIN
   utl_smtp.write_data(conn, utl_tcp.CRLF);
   IF (last) THEN
      write_boundary(conn, last);
   END IF;
END;

------------------------------------------------------------------------
PROCEDURE end_mail(conn IN OUT NOCOPY utl_smtp.connection) IS
BEGIN
   end_mail_in_session(conn);
   end_session(conn);
END;

------------------------------------------------------------------------
FUNCTION begin_session RETURN utl_smtp.connection IS
   conn utl_smtp.connection;
BEGIN
   -- open SMTP connection
   conn := utl_smtp.open_connection(smtp_host, smtp_port);
--   utl_smtp.helo(conn, smtp_domain);
   utl_smtp.ehlo(conn, smtp_domain);

   -- авторизация
/*
   utl_smtp.command(conn, 'AUTH LOGIN');
   utl_smtp.command(conn, utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('TrapezinA'))));
   utl_smtp.command(conn, utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw('password'))));
*/
   RETURN conn;
END;

------------------------------------------------------------------------
PROCEDURE begin_mail_in_session(
   conn       IN OUT NOCOPY utl_smtp.connection,
   sender     IN VARCHAR2,
   recipients IN VARCHAR2,
   subject    IN VARCHAR2,
   mime_type  IN VARCHAR2  DEFAULT 'text/plain',
   priority   IN PLS_INTEGER DEFAULT NULL) IS
   my_recipients VARCHAR2(32767) := recipients;
   my_sender     VARCHAR2(32767) := sender;
BEGIN
   utl_smtp.mail(conn, get_address(my_sender));
   WHILE (my_recipients IS NOT NULL) LOOP
      utl_smtp.rcpt(conn, get_address(my_recipients));
   END LOOP;
   -- Start body of email
   utl_smtp.open_data(conn);
   -- Set "From" MIME header
   write_mime_header(conn, 'From', sender);
   -- Set "To" MIME header
   write_mime_header(conn, 'To', recipients);
   -- Set "Subject" MIME header
   write_mime_header(conn, 'Subject', subject);
   -- Set "Content-Type" MIME header
   write_mime_header(conn, 'Content-Type', mime_type);
   -- Set "X-Mailer" MIME header
   write_mime_header(conn, 'X-Mailer', MAILER_ID);
   -- Set priority:
   --   High      Normal       Low
   --   1     2     3     4     5
   IF (priority IS NOT NULL) THEN
      write_mime_header(conn, 'X-Priority', priority);
   END IF;

   -- Send an empty line to denotes end of MIME headers and
   -- beginning of message body.
   utl_smtp.write_data(conn, utl_tcp.CRLF);

   IF (mime_type LIKE 'multipart/mixed%') THEN
      write_text(conn, 'This is a multi-part message in MIME format.'||utl_tcp.crlf);
   END IF;
END;

  ------------------------------------------------------------------------
  PROCEDURE end_mail_in_session(conn IN OUT NOCOPY utl_smtp.connection) IS
  BEGIN
    utl_smtp.close_data(conn);
  END;
   
------------------------------------------------------------------------
PROCEDURE end_session(conn IN OUT NOCOPY utl_smtp.connection) IS
BEGIN
   utl_smtp.quit(conn);
END;

-- отправить письмо с вложением файла
-- файл должен существовать на локальном диске!
procedure send_mail_with_attach(
   sender     IN VARCHAR2, -- отправитель
   recipients IN VARCHAR2,   -- получатели
   subject    IN VARCHAR2, -- тема сообщения
   message    IN VARCHAR2, -- тело сообщения
   file_path  IN VARCHAR2, -- путь к файлу
   file_name  IN VARCHAR2, -- имя файла
   mime_type  IN VARCHAR2 DEFAULT 'text/plain'
) is
f      number;
dat   raw(2000);
conn   utl_smtp.connection;
begin
   conn := begin_mail(
      sender,
      recipients,
      subject,
      MULTIPART_MIME_TYPE||' charset="windows-1251"'
   );
   -- положим тело сообщения
   if message is not null then
      attach_text(conn, message, mime_type);
   end if;
   begin
      f:=STDIO.OPEN(file_path, file_name, 'r');
   exception
   when others then
      if sqlcode in (-4061,-6508) then raise; end if;
--      RTL.DEBUG_PIPE('Ошибка при открытии файла: '||SQLERRM,0);
   end;
   if STDIO.IS_OPEN(f) then
      begin_attachment(conn, mime_type, FALSE, file_name);
      loop
         if stdio.f_read(f, dat, 2000)>0 then
            write_raw(conn, dat);
         else
            exit;
         end if;
      end loop;
      stdio.close(f);
      end_attachment(conn, true);
   end if;
   end_mail(conn);
end;

-- отправить письмо с вложенными файлами
-- файлы должены существовать на локальном диске сервера!
procedure send_mail_with_attachments(
   sender     IN VARCHAR2, -- отправитель
   recipients IN VARCHAR2,   -- получатели
   subject    IN VARCHAR2, -- тема сообщения
   message    IN VARCHAR2, -- тело сообщения
   files  IN attach_tbl, -- файлы для вложения
   mime_type  IN VARCHAR2 DEFAULT 'text/plain'
) is
f      number;
dat   raw(2000);
conn   utl_smtp.connection;
b_att   boolean   :=   false;
begin
   conn := begin_mail(
      sender,
      recipients,
      subject,
      MULTIPART_MIME_TYPE||' charset="windows-1251"'
   );
   -- положим тело сообщения
   if message is not null then
      attach_text(conn, message, mime_type);
   end if;
   if files.count > 0 then   -- есть список вложений
      for idx in files.first..files.last loop
         begin
            f := STDIO.OPEN(trim(files(idx).file_path), trim(files(idx).file_name), 'r');
         exception
         when others then
            if sqlcode in (-4061,-6508) then raise; end if;
            RTL.DEBUG('UTL_SMTP$: sqlerrm = '||sqlerrm,3,true);
            goto end$loop$1;   -- файл не смог открыться, берем следующий
         end;
         if STDIO.IS_OPEN(f) then
            RTL.DEBUG('UTL_SMTP$: add attach name = '||trim(files(idx).file_name),3,true);
            begin_attachment(conn, mime_type, FALSE, trim(files(idx).file_name));
            if not b_att then
               b_att := true;
            end if;
            loop
               if stdio.f_read(f, dat, 2000)>0 then
                  write_raw(conn, dat);
               else
                  exit;
               end if;
            end loop;
            stdio.close(f);
         end if;
         <<end$loop$1>>
         null;
      end loop;
   end if;
   if b_att then
      end_attachment(conn, true);
   end if;
   end_mail(conn);
end;

end UTL_SMTP$;


ЗЫ: авторских прав нет, пользуйтесь на здоровье)))
SkyLynx
Участник


Вступление в Клуб: 30.06.2007
СообщениеПн Апр 28, 2008 06:05    Ответить с цитатой
Полезность: Нет оценки
забыл про типы, вот они:
Код:
create or replace package UTL_SMTP$ is
/*
   author         Alexandr Trapezin
   created date   27/07/2005
   comment         Библиотека для работы с SMTP
   oracle         9.0.2 или выше
*/

   smtp_host   VARCHAR2(256); -- почтоный сервер
   smtp_port   PLS_INTEGER;   -- порт почтового сервера
   smtp_domain VARCHAR2(256); -- домен
   mail_charset   varchar2(256);   -- кодировка письма

   MAILER_ID   CONSTANT VARCHAR2(256) := 'Mailer by iBank';
 
   BOUNDARY        CONSTANT VARCHAR2(256) := '-----7D81B75CCC90D2974F7A1CBD';
   FIRST_BOUNDARY  CONSTANT VARCHAR2(256) := '--'||BOUNDARY||utl_tcp.CRLF;
   LAST_BOUNDARY   CONSTANT VARCHAR2(256) := '--'|| BOUNDARY||'--'||utl_tcp.CRLF;

   MULTIPART_MIME_TYPE CONSTANT VARCHAR2(256) := 'multipart/mixed; boundary="'||BOUNDARY ||'"';
   MAX_BASE64_LINE_WIDTH CONSTANT PLS_INTEGER   := 76 / 4 * 3;
   
   -- структура вложений
   type attach_type is record (
      file_path   varchar2(256),
      file_name   varchar2(256)
   );
   type attach_tbl is table of attach_type index by binary_integer;

   -- отправка текстового сообщения
   -- получатели разделяются знаками "," или ";"
   PROCEDURE mail(
      sender     IN VARCHAR2,   -- Отправитель
      recipients IN VARCHAR2,   -- получатели
      subject    IN VARCHAR2,   -- тема
      message    IN VARCHAR2,   -- сообщение
      mime_type  IN VARCHAR2 DEFAULT 'text/plain'
   );

   -- отправить письмо с вложением файла
   -- файл должен существовать на локальном диске сервера!
   procedure send_mail_with_attach(
      sender     IN VARCHAR2, -- отправитель
      recipients IN VARCHAR2,   -- получатели
      subject    IN VARCHAR2, -- тема сообщения
      message    IN VARCHAR2, -- тело сообщения
      file_path  IN VARCHAR2, -- путь к файлу
      file_name  IN VARCHAR2, -- имя файла
      mime_type  IN VARCHAR2 DEFAULT 'text/plain'
   );

   -- отправить письмо с вложенными файлами
   -- файлы должены существовать на локальном диске сервера!
   procedure send_mail_with_attachments(
      sender     IN VARCHAR2, -- отправитель
      recipients IN VARCHAR2,   -- получатели
      subject    IN VARCHAR2, -- тема сообщения
      message    IN VARCHAR2, -- тело сообщения
      files  IN attach_tbl, -- файлы для вложения
      mime_type  IN VARCHAR2 DEFAULT 'text/plain'
   );

     -- расширеная функция отправки сообщения
     -- функция возвращает соединение которое может использоваться для операция write_text() и write_mb_text()
     -- соединение должно явно закрываться операцией end_mail()
   FUNCTION begin_mail(
      sender     IN VARCHAR2,
      recipients IN VARCHAR2,
      subject    IN VARCHAR2,
      mime_type  IN VARCHAR2    DEFAULT 'text/plain',
      priority   IN PLS_INTEGER DEFAULT NULL
   ) RETURN utl_smtp.connection;

   -- запись строки в тело сообщения в ASCII
   PROCEDURE write_text(
      conn    IN OUT NOCOPY utl_smtp.connection,   -- соединение
      message IN VARCHAR2   -- сообщение
   );

   -- запись строки в тело сообщения не в ASCII
   PROCEDURE write_mb_text(
      conn    IN OUT NOCOPY utl_smtp.connection,
      message IN            VARCHAR2
   );
 
     -- запись в тело сообщения бинарные данные
   PROCEDURE write_raw(
      conn    IN OUT NOCOPY utl_smtp.connection,
      message IN RAW
   );

  -- APIs to send email with attachments. Attachments are sent by sending
  -- emails in "multipart/mixed" MIME format. Specify that MIME format when
  -- beginning an email with begin_mail().
 
   -- отправка текстового вложения
   PROCEDURE attach_text(
      conn         IN OUT NOCOPY utl_smtp.connection,
      data         IN VARCHAR2,
      mime_type    IN VARCHAR2 DEFAULT 'text/plain',
      inline       IN BOOLEAN  DEFAULT TRUE,
      filename     IN VARCHAR2 DEFAULT NULL,
      last         IN BOOLEAN  DEFAULT FALSE
   );
 
   -- отправка бинарного вложения в формате Base-64
   PROCEDURE attach_base64(
      conn         IN OUT NOCOPY utl_smtp.connection,
      data         IN RAW,
      mime_type    IN VARCHAR2 DEFAULT 'application/octet',
      inline       IN BOOLEAN  DEFAULT TRUE,
      filename     IN VARCHAR2 DEFAULT NULL,
      last         IN BOOLEAN  DEFAULT FALSE
   );
 
   -- отправка вложения
   PROCEDURE begin_attachment(
      conn         IN OUT NOCOPY utl_smtp.connection,   -- соединение
      mime_type    IN VARCHAR2 DEFAULT 'text/plain',   -- тип сообщения
      inline       IN BOOLEAN  DEFAULT TRUE,
      filename     IN VARCHAR2 DEFAULT NULL,         -- имя файла
      transfer_enc IN VARCHAR2 DEFAULT NULL         -- кодиродить или нет
   );
 
   -- закрытие вложения
   PROCEDURE end_attachment(
      conn IN OUT NOCOPY utl_smtp.connection,
      last IN BOOLEAN DEFAULT FALSE
   );
 
   -- закрытие соединения
   PROCEDURE end_mail(
      conn IN OUT NOCOPY utl_smtp.connection
   );

   -- операции для работы с сесиями
   FUNCTION begin_session RETURN utl_smtp.connection;
 
   -- начало сесии
   PROCEDURE begin_mail_in_session(
      conn       IN OUT NOCOPY utl_smtp.connection,
      sender     IN VARCHAR2,
      recipients IN VARCHAR2,
      subject    IN VARCHAR2,
      mime_type  IN VARCHAR2  DEFAULT 'text/plain',
      priority   IN PLS_INTEGER DEFAULT NULL
   );
 
   -- закрытие сесии
   PROCEDURE end_mail_in_session(conn IN OUT NOCOPY utl_smtp.connection);
 
   -- окончание сессии
   PROCEDURE end_session(conn IN OUT NOCOPY utl_smtp.connection);
end UTL_SMTP$;
biv
Участник


Вступление в Клуб: 05.07.2007
СообщениеПн Май 12, 2008 06:35    Ответить с цитатой
Полезность: Нет оценки
также была задача передавать сообщения предлагаю рабочее решение. тема сообщение (русский) и возможность отправки файлов вложения большой длины (там есть подводный камень длину
1200 не меняете или она должна быть кратна или 3 или 4 забыл

Код:


procedure send_header(name varchar2) is begin utl_smtp.write_raw_data(v_con, UTL_RAW.cast_to_raw(name||utl_tcp.CRLF)); end;

procedure send_sodfil(namefile varchar2) is
g#file integer;
buf varchar2(32002);
dl integer;
begin

  g#file   := stdio.open([SYSTEM_PARAMS]::[GET]('PATH', null),namefile,'r');
  loop
      dl:=stdio.fread (g#file, 12000, buf);
      utl_smtp.write_raw_data(V_con,utl_encode.base64_encode(buf));
      if dl is null or dl<12000 then exit; end if;
      buf:=null;
    end loop;
  stdio.fclose(g#file);
end;


procedure send_email(
p_send varchar2,     --ip кому
p_recip varchar2,    --ip от кого
tema varchar2,       -- тема
p_message varchar2,  -- сообщение
filename varchar2,   -- файл вложения
ips varchar2 default '172.16.2.1' -- ip почтового сервера
) is


vk       varchar2:=utl_tcp.CRLF;
v_mail   varchar2(255);
bound    varchar2(256) :='----------CE19416D1AA9BE2E';
begin
  v_mail  :=ips;
  v_con:=UTL_SMTP.open_connection(v_mail,25);
  UTL_SMTP.helo(v_con,v_mail);
  UTL_SMTP.mail(v_con,p_recip);
  UTL_SMTP.rcpt(v_con,p_send);
  UTL_SMTP.open_data(v_con);
  send_header('From: '||p_recip);
  send_header('To: '||p_send );
  send_header('Subject: '||nvl(tema,'Send PSKB (Oracle)') );
--  send_header('Date: '||TO_CHAR(SYSDATE,'dd Mon yy hh24:mi:ss'));
  send_header('MIME-Version: 1.0');

  send_header('Content-Type: multipart/mixed;  boundary="----------CE19416D1AA9BE2E"'||vk );

  send_header('------------CE19416D1AA9BE2E');
  send_header('Content-Type: text/plain; charset="koi8-r"'||vk);
  send_header(convert(p_message,'CL8KOI8R')||vk);
  if filename is not null then
    send_header('------------CE19416D1AA9BE2E');

    send_header('Content-Type: application/octet-stream;');
    send_header(' name="'||filename||'"');
    send_header('Content-transfer-encoding: base64');
    send_header('Content-Disposition: attachment;');
    send_header(' filename="'||filename||'"'||vk);
    send_sodfil(filename);
    send_header(vk);
    send_header('------------CE19416D1AA9BE2E--');
  end if;
  UTL_SMTP.close_data(v_con);
  UTL_SMTP.quit(v_con);
end;
ГлСП
Профи


Вступление в Клуб: 20.09.2007
СообщениеВт Авг 19, 2008 05:26    Ответить с цитатой
Полезность: Нет оценки
Я вот таким способом реализовал рассылку

Код:

Begin
list_mail   :=   'mail1@bank.ru,mail2@bank.ru,mail3@bank.ru'
head   :=   stdio.TRANSFORM('Заголовок', Stdio.UNXTEXT, Stdio.WINTEXT);
msg_text   :=   Stdio.Transform('Текст сообщения', Stdio.UNXTEXT , Stdio.KOITEXT);
-- begin pl/sql
exit_status := sys.mail_utl.send_mail ( return_address => 'from@bank.ru',recipient_list => list_mail,subject_line => head, message_text => msg_text);
-- end pl/sql   
End;


Все работает, но есть минус. Требует установку пакета mail_utl. На юниксовый оракл встает нормально, на счет других, не знаю.
svenson
Участник


Вступление в Клуб: 24.04.2008
СообщениеЧт Авг 28, 2008 11:05    Ответить с цитатой
Полезность: Нет оценки
Да в интернете если покапаться можно найти уже готовые пакеты для отправки почты Smile
Я, например, использовал такой:

Код:

CREATE OR REPLACE PACKAGE IBS.Mail_Pack AS
TYPE ARRAY_OF_VARCHAR2_TYPE IS TABLE OF VARCHAR2(255);

TYPE SMTP_Service is record
(
  g_mailhost    VarChar2(255),
  g_Port        Integer ,
  CodePage      VarChar2(20) ,
  L_CodePage    VarChar2(20) ,
  l_date        VarChar2(255) ,
  Content_Delimiter VarChar2(100) ,
  g_mail_conn   sys.Utl_SMTP.Connection ,
  SndBuf        VarChar2(3),
  g_crlf        Char(2) ,
  Base64XLAT    Char(64) ,
  EncBuf        VarChar2(4096),
  ContentAutoTranslate char(1)
) ;

  procedure SMTP_Service_Init( Self out nocopy SMTP_Service, aMailHost varchar2 ) ;
  procedure ConnOpen(Self in out nocopy SMTP_Service);
  procedure send_start(Self in out nocopy SMTP_Service,
    p_sender_email in VarChar2,
    p_from         in VarChar2,
    p_to           in ARRAY_OF_VARCHAR2_TYPE default ARRAY_OF_VARCHAR2_TYPE(),
    p_cc           in ARRAY_OF_VARCHAR2_TYPE default ARRAY_OF_VARCHAR2_TYPE(),
    p_bcc          in ARRAY_OF_VARCHAR2_TYPE default ARRAY_OF_VARCHAR2_TYPE(),
    p_subject      in VarChar2 default null,
    p_body         in Long default null ) ;
  procedure Send_Attachment_Start(Self in out nocopy SMTP_Service, Name in VarChar2 );
  procedure Send_Attachment_Part( Self in out nocopy SMTP_Service, Content in VarChar2 );
  procedure Send_Attachment_Finish(Self in out nocopy SMTP_Service);
  procedure send_finish(Self in out nocopy SMTP_Service);
  procedure ConnClose(Self in out nocopy SMTP_Service);
END Mail_Pack;
/

CREATE OR REPLACE PACKAGE BODY IBS.MAIL_PACK AS
  -- Формирует строку адреса по списку
  function Address_EMail( Self in out nocopy SMTP_Service,
    Prefix in VarChar2,
    Rcpts in ARRAY_OF_VARCHAR2_TYPE
    ) return VarChar2 is
    l_rcpts Long ;
    i integer ;
  begin
    if (Rcpts is null) or (Rcpts.Count < 1) then
      return '' ;
    end if ;
    sys.Utl_SMTP.Rcpt(Self.g_mail_conn, Rcpts(1) ) ;
    l_rcpts := Prefix||Rcpts(1) ;
    for i in 2..Rcpts.Count
    loop
      sys.Utl_SMTP.Rcpt(Self.g_mail_conn, Rcpts(i) ) ;
      l_rcpts := l_rcpts || ', ' || Rcpts(i) ;
    end loop ;
    return l_rcpts ;
  end ; -- Address_EMail

  procedure WriteData( Self in out nocopy SMTP_Service, p_text IN VARCHAR2 ) as
  begin
    if p_text is not null then
      Utl_SMTP.Write_raw_Data( Self.g_mail_conn, utl_raw.cast_to_raw(convert(p_text, Self.CodePage ) || self.g_crlf) ) ;
    end if ;
  end ; -- WriteData

  procedure SendHeader(Self in out nocopy SMTP_Service, name in varchar2, header in varchar2) as
  begin
    WriteData(self,name||': '||header) ;
  end ; -- SendHeader

  procedure WriteBase64( Self in out nocopy SMTP_Service, Buffer in RAW ) as
    summ BINARY_INTEGER; -- суммарный код - трехбайтовое слово
    c1 NUMBER(2); -- код 1-го символа
    c2 NUMBER(2); -- код 2-го символа
    c3 NUMBER(2); -- код 3-го символа
    c4 NUMBER(2); -- код 4-го символа     
  begin
    summ:=to_number(rawtohex(buffer),'xxxxxxxx');
    c1:=bitand(summ,16515072)/262144;
    c2:=bitand(summ,258048)/4096;
    c3:=bitand(summ,4032)/64;
    c4:=bitand(summ,63);
    Self.EncBuf:=Self.EncBuf||
      substr(Self.Base64XLAT,c1+1,1)||
      substr(Self.Base64XLAT,c2+1,1)||
      substr(Self.Base64XLAT,c3+1,1)||
      substr(Self.Base64XLAT,c4+1,1) ;
    if length(Self.EncBuf) > 2044 then
      utl_smtp.write_raw_data(Self.g_mail_conn, utl_raw.cast_to_raw(Self.EncBuf) ) ;
      Self.EncBuf := '' ;
    end if ;
  end ; -- WriteBase64

  procedure SMTP_Service_Init( Self out nocopy SMTP_Service, aMailHost varchar2 ) is
  begin
    Self.g_mailhost := aMailHost ;
    Self.g_Port := 25 ;
    Self.g_CrLf := Chr(13)||Chr(10);
    Self.Content_Delimiter := '----====02EE0956@_@38084.18228931@_@0C064' ;
    Self.CodePage := 'CL8MSWIN1251' ;
    Self.L_CodePage := 'windows-1251' ;
    Self.L_date := null ;
    Self.Base64XLAT :='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';   
    Self.ContentAutoTranslate := 'Y' ;
  end ; -- SMTP_Service

  procedure ConnOpen(Self in out nocopy SMTP_Service) is
  begin
    Self.g_mail_conn := utl_smtp.open_connection(Self.g_mailhost, Self.g_Port);
    utl_smtp.helo(Self.g_mail_conn, Self.g_mailhost);
  end ; -- ConnOpen

  procedure send_start(Self in out nocopy SMTP_Service,
    p_sender_email in VarChar2,
    p_from         in VarChar2,
    p_to           in ARRAY_OF_VARCHAR2_TYPE default ARRAY_OF_VARCHAR2_TYPE(),
    p_cc           in ARRAY_OF_VARCHAR2_TYPE default ARRAY_OF_VARCHAR2_TYPE(),
    p_bcc          in ARRAY_OF_VARCHAR2_TYPE default ARRAY_OF_VARCHAR2_TYPE(),
    p_subject      in VarChar2 default null,
    p_body         in Long default null ) is
    l_to_list varchar2(4096);
    l_cc_list varchar2(4096);
    l_bcc_list varchar2(4096);
  begin
    utl_smtp.mail(Self.g_mail_conn, p_sender_email);
    l_to_list := address_email( Self, 'To: ', p_to );
    l_cc_list := address_email( Self, 'Cc: ', p_cc );
    l_bcc_list := address_email( Self, 'Bcc: ', p_bcc );
    utl_smtp.open_data(Self.g_mail_conn );
    SendHeader(Self, 'Date',NVL(Self.l_date,TO_CHAR( SYSDATE, 'dd Mon yy hh24:mi:ss' ) ));
    SendHeader(Self, 'From',NVL(p_from, p_sender_email));
    SendHeader(Self, 'Subject',NVL(p_subject,'(no subject)') ) ;
    SendHeader(Self, 'MIME-Version','1.0');
    SendHeader(Self, 'Content-Type','multipart/mixed; boundary="'||substr(Self.Content_Delimiter,3,255)||'"');
    WriteData(Self, Self.Content_Delimiter);
    SendHeader(Self, 'Content-Type','text/plain; charset="'||Self.l_CodePage||'"');
    SendHeader(Self, 'Content-Transfer-Encoding','8bit');
    WriteData(Self, l_to_list );
    WriteData(Self, l_cc_list );
    WriteData(Self, Self.g_crlf||p_body);
    --WriteData(Self, Self.Content_Delimiter);
  end ; -- send_start

  procedure Send_Attachment_Start(Self in out nocopy SMTP_Service, Name in VarChar2 ) is
  begin
    WriteData(Self,Self.g_crlf||Self.Content_Delimiter);
    SendHeader(Self,'Content-Type','application/octet-stream; name="'||name||'"');
    SendHeader(Self,'Content-Transfer-Encoding','base64');
    Self.SndBuf := '' ;
    Self.EncBuf := '' ;
  end ; -- Send_Attachment_Start

  procedure P_Send_Attachment_Part( Self in out nocopy SMTP_Service, Content in VarChar2 ) is
    i integer ;
  begin
    if Self.SndBuf is null then
      I := 1 ;
    else
      I := 4 - Length(Self.SndBuf) ;
      Self.SndBuf := SubStr(Self.SndBuf||SubStr(Content,1,2),1,3) ;
      if Length(Self.SndBuf) = 3 then
        WriteBase64(Self,utl_raw.cast_to_raw(SubStr(Content,I,3))) ;
      end if ;
    end if ;
    if I <= Length(Content) then
      loop
        Exit when I + 3 > Length(Content) ;
        WriteBase64(Self,utl_raw.cast_to_raw(substr(Content,I,3))) ;
        I := I + 3 ;
      end loop ;
      Self.SndBuf := SubStr(Content,I,3) ;
    end if ;
  end ; -- P_Send_Attachment_Part
 
  procedure Send_Attachment_Part( Self in out nocopy SMTP_Service, Content in VarChar2 ) is
  begin
    if Self.ContentAutoTranslate = 'Y' then
      P_Send_Attachment_Part( Self, convert(Content, Self.CodePage )) ;
    else
      P_Send_Attachment_Part( Self, Content) ;
    end if ;
  end ; -- Send_Attachment_Part

  procedure Send_Attachment_Finish(Self in out nocopy SMTP_Service) is
    c char(3) ;
  begin
    if Self.SndBuf is not null then
      c := Self.SndBuf ;
      WriteBase64(Self,utl_raw.cast_to_raw(c) );
    end if ;
    if Self.EncBuf is not null then
      utl_smtp.write_raw_data(Self.g_mail_conn, utl_raw.cast_to_raw(Self.EncBuf) ) ;
      Self.EncBuf := '' ;
    end if ;
  end ; -- Send_Attachment_Finish

  procedure send_finish(Self in out nocopy SMTP_Service) is
  begin
    utl_smtp.close_data(Self.g_mail_conn ) ;
  end ; -- send_finish

  procedure ConnClose(Self in out nocopy SMTP_Service) is
  begin
    utl_smtp.quit(Self.g_mail_conn);
  end ; -- ConnClose
END MAIL_PACK;



Использовать его можно, например, так:

Код:

procedure send_mail(p_mailhost in VarChar2(255), p_sender in VarChar2, p_from in VarChar2, p_to in Varchar2, p_subject in VarChar2, p_body in string_32000) is
-- begin pl/sql
   s Mail_Pack.smtp_service ;
-- end pl/sql
begin
   -- begin pl/sql
   Mail_Pack.SMTP_Service_Init(s, p_mailhost) ;
    Mail_Pack.ConnOpen(s) ;
    Mail_Pack.send_start(s, p_sender,
                      p_from,
                       Mail_Pack.ARRAY_OF_VARCHAR2_TYPE(p_to),
                        null,
                        null,
                        p_subject,
                        p_body);
    Mail_Pack.send_finish(s) ;
    Mail_Pack.ConnClose(s) ;
   -- end pl/sql
end;
belyansky
Участник со стажем


Вступление в Клуб: 22.10.2007
СообщениеЧт Сен 18, 2008 08:00    Ответить с цитатой
Полезность: Нет оценки
Добрый день! пример SkyLynx очень полезный, использовал его, можно сказать всё отрабатывает отлично. Но возникла проблема - нужно подтягивать файл во вложение. Вопрос в том, как записывать список вложений?
Я просто для примера сделал так:
files(1).file_path := 'C:\TEST';
files(1).file_name := 'test.txt';

файл не подтягивается.
YuSokolov
Профи


Вступление в Клуб: 29.06.2007
СообщениеЧт Сен 18, 2008 08:20    Ответить с цитатой
Полезность: Нет оценки
belyansky пишет:
...Я просто для примера сделал так:
files(1).file_path := 'C:\TEST';...

а если добавить "\"
files(1).file_path := 'C:\TEST\'
dnk_dz
Эксперт


Вступление в Клуб: 19.09.2007
СообщениеЧт Сен 18, 2008 08:29    Ответить с цитатой
Полезность: Нет оценки
belyansky пишет:
Добрый день! пример SkyLynx очень полезный, использовал его, можно сказать всё отрабатывает отлично. Но возникла проблема - нужно подтягивать файл во вложение. Вопрос в том, как записывать список вложений?
Я просто для примера сделал так:
files(1).file_path := 'C:\TEST';
files(1).file_name := 'test.txt';

файл не подтягивается.


Я так подозреваю, что файл должен быть на сервере Wink
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Справочник PL/PLUS: Функции, примеры, приёмы Часовой пояс: GMT + 3
На страницу Пред.  1, 2, 3  След.
Страница 2 из 3

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru