沸騰冷水

煮え滾った熱い思いを氷のように冷たく見つめなおしたい

OracleのPL/SQLでメールを送信する

OraclePL/SQLアプリケーションからメールを送信できるのか

アプリケーションを実行し、あるアクションのタイミングでメールを送信したい。
そんな時はOSのコマンドではなく、PL/SQLからメールを送信したいと思う。
というわけでPL/SQLからメールを送信する方法について調べた。

環境

・Oracle9i(9.2.0.4)
・AIX5.3

方法

ユーティリティのUTL_SMTPパッケージを使います。
UTL_SMTP
上記サイトの「UTL_SMTP」の使用方法→「例」にサンプルコードがあります。

DECLARE
  c UTL_SMTP.CONNECTION;

  PROCEDURE send_header(name IN VARCHAR2, header IN VARCHAR2) AS
  BEGIN
    UTL_SMTP.WRITE_DATA(c, name || ': ' || header || UTL_TCP.CRLF);
  END;

BEGIN
  c := UTL_SMTP.OPEN_CONNECTION('smtp-server.acme.com');
  UTL_SMTP.HELO(c, 'foo.com');
  UTL_SMTP.MAIL(c, 'sender@foo.com');
  UTL_SMTP.RCPT(c, 'recipient@foo.com');
  UTL_SMTP.OPEN_DATA(c);
  send_header('From',    '"Sender" <sender@foo.com>');
  send_header('To',      '"Recipient" <recipient@foo.com>');
  send_header('Subject', 'Hello');
  UTL_SMTP.WRITE_DATA(c, UTL_TCP.CRLF || 'Hello, world!');
  UTL_SMTP.CLOSE_DATA(c);
  UTL_SMTP.QUIT(c);
EXCEPTION
  WHEN utl_smtp.transient_error OR utl_smtp.permanent_error THEN
    BEGIN
      UTL_SMTP.QUIT(c);
    EXCEPTION
      WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN
        NULL; -- When the SMTP server is down or unavailable, we don't have
              -- a connection to the server. The QUIT call will raise an
              -- exception that we can ignore.
    END;
    raise_application_error(-20000,
      'Failed to send mail due to the following error: ' || sqlerrm);
END;

10行目〜16行目のアドレスを変更すればとりあえずメールの送信は可能になります。


しかし、このままでは日本語を含むマルチバイトコードが送信できません。
日本語を UTL_SMTP.WRITE_DATA に含めても文字化けしてしまいます。
日本語を送信するには、マルチバイトコードをRAWに変換し、メール文面に含める必要があるようです。

18行目

UTL_SMTP.WRITE_DATA(c, UTL_TCP.CRLF || 'Hello, world!');

に変更が必要です。

メール本文を書き込む関数として、もう一つ、UTL_SMTP.WRITE_RAW_DATA 関数があります。
こちらを使って、メール本文にRAWデータを渡してあげます。

上記18行目を例としましょう。
'Hello, world!' を 'ほげ' にして日本語を送ります。

UTL_SMTP.WRITE_RAW_DATA(c, UTL_RAW.CAST_TO_RAW(UTL_TCP.CRLF || 'ほげ'));

RAW型のデータを関数に渡すため、本文データをそのまま、UTL_RAWパッケージのCAST_TO_RAW関数を使って、RAW型に変換しています。
このとき、UTL_TCP.CRLF の改行コードも一緒にRAW型に変換する必要があります。

以上

UTL_SMTPには他にも添付ファイルを含める方法などがありますので、ご利用の際にはぜひ一読を。