Skip to Main Content
  • Questions
  • Sending e-mail! -- Oracle 8i specific response

Breadcrumb

May 4th

Question and Answer

Tom Kyte

Thanks for the question, Leonardo.

Asked: May 30, 2000 - 4:53 pm UTC

Last updated: December 16, 2021 - 9:24 am UTC

Version: 8.1.5

Viewed 100K+ times! This question is

You Asked

How to send personalized email to clients registered in my portal www.intrainternet.com using the information stored in our Database Oracle 8i automatically?


and Connor said...

(note: Comments are blocked on this question due to the spam volume we're getting)

This is a sample chapter from my book Expert One on One Oracle -- it describes how to send email from Oracle versions 816 and higher (the java only approach described about halfway through works in 815 and higher)

UTL_SMTP and sending mail

UTL_SMTP, introduced for the first time in Oracle 8.1.6, is an interface to the Simple Mail Transfer Protocol. It requires that you have an SMTP server in your network somewhere ? most sites I have been to have at least one SMTP server running as it is the most popular method for sending mail.

The UTL_SMTP package is best suited for sending small, text only emails from the database. While its API supports the sending of attachments and everything else ? it is left to you to actually encode the multi-part document ? for example turning binary attachments into mime-encoded documents.

We've already seen how to use UTL_SMTP in the DBMS_JOB section where we made it 'apparently' execute faster by doing it asynchronously. In this section we?ll revisit that example, build upon it ? adding additional functionality. We will also look at an alternative to UTL_SMTP that provides somewhat much more functionality ? including the ability to easily send attachments with the email. Since SMTP is a very low level protocol, we'll reuse existing public domain code to get an SMTP interface at much higher level ? and we'll get it with very little code.

UTL_SMTP ? a larger example

In the DBMS_JOB section, we explored how to make sending email using UTL_SMTP appear to execute faster. We also made email transactional in nature in that section ? if you rollback the email does not get sent, if you commit ? out it goes. I highly recommend the use of DBMS_JOB as a layer on your emails routines for these reasons. In that section, the example UTL_SMTP routine we used was:

tkyte@TKYTE816> create or replace
2 PROCEDURE send_mail (p_sender IN VARCHAR2,
3 p_recipient IN VARCHAR2,
4 p_message IN VARCHAR2)
5 as
6 l_mailhost VARCHAR2(255) := 'aria.us.oracle.com';
7 l_mail_conn utl_smtp.connection;
8 BEGIN
9 l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
10 utl_smtp.helo(l_mail_conn, l_mailhost);
11 utl_smtp.mail(l_mail_conn, p_sender);
12 utl_smtp.rcpt(l_mail_conn, p_recipient);
13 utl_smtp.open_data(l_mail_conn );
14 utl_smtp.write_data(l_mail_conn, p_message);
15 utl_smtp.close_data(l_mail_conn );
16 utl_smtp.quit(l_mail_conn);
17 end;
18 /
Procedure created.

tkyte@TKYTE816> begin
2 send_mail( 'thomas.kyte@oracle.com',
3 'tkyte@oracle.com',
4 'Hello Tom' );
5 end;
6 /

PL/SQL procedure successfully completed.

That works OK but is very limited in nature. It sends email to exactly one recipient, you cannot CC or BCC anyone, you cannot setup a subject -- the email always arrives with a ?blank? subject line. We would like to support more options with this package.

A full discussion of all of the possibilities with UTL_SMTP would require in depth knowledge of the SMTP protocol itself ? something that is outside the scope of this book. Readers interested in all of the opportunities available with SMTP should review RFC812 ? which is the description of SMTP. This is available online at </code> http://www.faqs.org/rfcs/rfc821.html
 Below, I will simply present how to send an email using UTL_SMTP that supports:

o Multiple ?to? recipients
o Multiple ?cc? recipients
o Multiple ?bcc? recipients
o A single body of up to 32k in size
o A subject line
o A descriptive ?from? line (instead of showing just the email address as the ?from? in the email client)

A specification for a PLSQL package that supports this might look like the following.  In here, we define an array type to allow for a caller to easily send a list of recipients as well as provide the external specification of the PLSQL routine we will be implementing:

tkyte@TKYTE816> create or replace package mail_pkg
  2  as
  3          type array is table of varchar2(255);
  4
  5          procedure send( p_sender_email in varchar2,
  6                          p_from         in varchar2,
  7                          p_to           in array default array(),
  8                          p_cc           in array default array(),
  9                          p_bcc          in array default array(),
 10                          p_subject      in varchar2,
 11                          p_body         in long );
 12  end;
 13  /
Package created.

The package body for this implementation is relatively straightforward ? if understand just enough of the SMTP protocol and what an email looks like (how email clients get the From, To, CC and so on).  Before we look at the code, we?ll look at what an email might actually look like. Consider the following ASCII text:

Date: 13 May 01 12:33:22
From: Oracle Database Account <asktom_us@oracle.com>
Subject: This is a subject
To: asktom_us@oracle.com, thomas.kyte@oracle.com
Cc: tkyte@oracle.com

Hello Tom, this is the mail you need

That is what you would transmit as the body of the email using UTL_SMTP to have the email client set the From, Subject, and so on.  There are no SMTP commands to do that magic, rather, this header information is placed right in the body of the email itself ? separated from the text of the email by a blank line.  Once we understand that ? sending an email with all of the options we need is pretty easy.  The only thing we need to understand beyond that is that in order to send the email to more then one recipient, we simply call UTL_SMTP.RCPT more then once ? with different names.  That?s all of the information we need to know then to send an email.

So, here is the package body.  We start with a couple of constants and globals.  You will of course need to change the g_mailhost to be the name of a server you have access to, Aria is my machine inside of Oracle ? you will not be able to access that:

tkyte@TKYTE816> create or replace package body mail_pkg
  2  as
  3
  4  g_crlf        char(2) default chr(13)||chr(10);
  5  g_mail_conn   utl_smtp.connection;
  6  g_mailhost    varchar2(255) := 'aria.us.oracle.com';
  7

Next we have an internal (unpublished) function to send an email to many recipients ? it in effect addresses the email.  At the same time, it builds the ?To:? or ?Cc:? lines that we?ll eventually send as part of the email itself and returns that formatted string.  It was implemented as a separate function since we need to do this separately for the To, CC, and BCC lists:

  8  function address_email( p_string in varchar2,
  9                          p_recipients in array ) return varchar2
 10  is
 11      l_recipients long;
 12  begin
 13     for i in 1 .. p_recipients.count
 14     loop
 15        utl_smtp.rcpt(g_mail_conn, p_recipients(i) );
 16        if ( l_recipients is null )
 17        then
 18            l_recipients := p_string || p_recipients(i) ;
 19        else
 20            l_recipients := l_recipients || ', ' || p_recipients(i);
 21        end if;
 22     end loop;
 23     return l_recipients;
 24  end;
 25
 26

Now we have the implementation of our published function ? the one people will actually call to send mail.  It starts with an internal procedure writeData that is used to simplify the sending of the email headers (the To:, From:, Subject: records).  If the header record is NOT NULL, this routine will use the appropriate UTL_SMTP call to send it ? along with the necessary end of line marker (the carriage return/line feed):

 27  procedure send( p_sender_email in varchar2,
 28                  p_from         in varchar2 default NULL,
 29                  p_to           in array default array(),
 30                  p_cc           in array default array(),
 31                  p_bcc          in array default array(),
 32                  p_subject      in varchar2 default NULL,
 33                  p_body         in long  default NULL )
 34  is
 35      l_to_list   long;
 36      l_cc_list   long;
 37      l_bcc_list  long;
 38      l_date      varchar2(255) default
 39                  to_char( SYSDATE, 'dd Mon yy hh24:mi:ss' );
 40
 41      procedure writeData( p_text in varchar2 )
 42      as
 43      begin
 44          if ( p_text is not null )
 45          then
 46              utl_smtp.write_data( g_mail_conn, p_text || g_crlf );
 47          end if;
 48      end;

Now we are ready to actually send the mai.  This part is not very different from the very simple routine we started with.  It begins in exactly the same fashion ? by connecting to the SMTP server and starting a session:

 49  begin
 50      g_mail_conn := utl_smtp.open_connection(g_mailhost, 25);
 51
 52      utl_smtp.helo(g_mail_conn, g_mailhost);
 53      utl_smtp.mail(g_mail_conn, p_sender_email);
 54

Here is where it differs, instead of calling UTL_SMTP.RCPT once ? it uses are address_email function to call it potentially many times, building the ?To:? and ?Cc:? list for us as well.  It builds the BCC list but we won?t actually send that (we don?t want the recipients to see that list!)

 55      l_to_list  := address_email( 'To: ', p_to );
 56      l_cc_list  := address_email( 'Cc: ', p_cc );
 57      l_bcc_list := address_email( 'Bcc: ', p_bcc );
 58

Now, we use the OPEN_DATA call to start sending the body of the email.  The code on lines 61 through 68 generates the header section of data.  Line 69 sends the body of the email (the contents of the email) and line 70 terminates the email for us. 

 59      utl_smtp.open_data(g_mail_conn );
 60
 61      writeData( 'Date: ' || l_date );
 62      writeData( 'From: ' || nvl( p_from, p_sender_email ) );
 63      writeData( 'Subject: ' || nvl( p_subject, '(no subject)' ) );
 64
 65      writeData( l_to_list );
 66      writeData( l_cc_list );
 67
 68      utl_smtp.write_data( g_mail_conn, '' || g_crlf );
 69      utl_smtp.write_data(g_mail_conn, p_body );
 70      utl_smtp.close_data(g_mail_conn );
 71      utl_smtp.quit(g_mail_conn);
 72  end;
 73
 74
 75  end;
 76  /
Package body created.

And that?s it, now since I have many email addresses (asktom_us@oracle.com, tkyte@oracle.com, thomas.kyte@oracle.com, utility@aria.us.oracle.com) I can test this API like this:

tkyte@TKYTE816> begin
  2      mail_pkg.send
  3      ( p_sender_email => 'asktom_us@oracle.com',
  4        p_from => 'Oracle Database Account <asktom_us@oracle.com>',
  5        p_to => mail_pkg.array( 'asktom_us@oracle.com',
                                           'thomas.kyte@oracle.com' ),
  6        p_cc => mail_pkg.array( 'tkyte@oracle.com' ),
  7        p_bcc => mail_pkg.array( 'utility@aria.us.oracle.com' ),
  8        p_subject => 'This is a subject',
  9        p_body => 'Hello Tom, this is the mail you need' );
 10  end;
 11  /

PL/SQL procedure successfully completed.

And that call is exactly what generated the ASCII text:

Date: 13 May 01 12:33:22
From: Oracle Database Account <asktom_us@oracle.com>
Subject: This is a subject
To: asktom_us@oracle.com, thomas.kyte@oracle.com
Cc: tkyte@oracle.com

Hello Tom, this is the mail you need

We saw above ? that is what got sent to all of those recipients ? including utility@aria.us.oracle.com, although we cannot see that recipient since it was bcc?ed.

That covers most of the typical uses of the UTL_SMTP supplied package.  Above I did say it is capable of sending email with attachments and such but that would require an inordinate amount of effort on our part.  We would have to:

o Learn how to format a multi-part mime encoded document, no small feat
o Base-64 encode binary data (or use some equivalent encoding technique such as uuencoding, binhex, and so on)

That would be (conservatively) a couple of hundred, if not thousands of lines of PL/SQL code.  Rather then do that, I will suggest that you use the already written and very robust JavaMail API as described below.

<b>
Loading and using the JavaMail API
</b>

In order to use the UTL_SMTP package, you must already have a Java enabled database in Oracle8i.  This is because UTL_SMTP relies on UTL_TCP and UTL_TCP in turn is built on Java functions. (Remember, if you don't have a Java enabled database you can use UTL_HTTP as described above to send simple emails). So, if you are able to use UTL_SMTP, you must have a Java enabled database, we can go to the Sun website and download their JavaMail API. This will give us the ability to send much more complicated emails from the database; including attachments. The following is based on work performed by a coworker of mine, Mark Piermarini who helps me out with lots of my Java issues.

If you go to 
http://java.sun.com/products/javamail/index.html,
you'll be able to download their JavaMail API. The download you get will consist of a couple of hundred files; only one of which we are interested in. After you download the JavaMail API ? make sure also to get their the JavaBeansTM Activation Framework extension or JAF (javax.activation). This is needed to run the JavaMail API package.

After you have downloaded these two sets of files ? you will need to extract mail.jar from the JavaMail APIdownload and activation.jar from the JAF download. This is all you will need from this ? feel free to read through the documentation, there is a lot of functionality in there we are not using, we are just using the 'send an email' part of the API. The API includes functions for receiving mail as well from IMAP, POP, and other sources.

We will need to load the mail.jar and activation.jar into the database using loadjava but before we can do that we must repackage them. These jar files are compressed in a format that is not understood by the database byte code interpreter. You need to 'unjar' and 'rejar' them without compression or use a tool such as WinZip to 'rejar' them into a zip file. What I did on Windows 2000 was:

1. Used WinZip to extract the contents of mail.jar into my c:\temp\mail directory
2. Used WinZip to create a new archive c:\temp\mail8i.zip
3. Put the contents of c:\temp\mail\*.* including subdirectories into this new archive

I did the same thing for activation.jar ? only replacing mail with activation in the above steps. Now we are ready to load these zip (or jar files, whatever you named them) into the database. These need to be loaded using the SYS user since they have 'protected' Java packages that regular users cannot upload. We will use the commands:

loadjava -u sys/manager -o -r -v -f -noverify -synonym -g public mail8i.zip
loadjava -u sys/manager -o -r -v -f -noverify -synonym -g public activation8i.zip

Where:

o -u sys/manager: is the userid and password for your SYS account.  As stated previously, some of the packages are protected and must be loaded as SYS
o -o: is shorthand for ?oci8, I am using the oci8 driver. You could use the thin driver as well but you'll need to modify the command to do so
o -r: is short for ?resolve. This will resolve all external references in the loaded classes helping to verify that the loaded java classes will be able to function after we load them
o -v: is short for ?verbose.  This gives us something to do while loadjava is running. We can see it work through each step of its process.
o -f: is short for ?force. This isn't necessary on the first load but is OK to use. If you try a loadjava and hit an error, you can correct it, and reload ? then you would either need to use the dropjava command to drop the jar file from the database or use ?force. Using ?force just makes it easier for us.
o -noverify: does not attempt to verify the bytecode. You must be granted oracle.aurora.security.JServerPermission(Verifier) to execute this option. In addition, this option must be used in conjunction with -r. SYS has this privilege. This is needed because the bytecode verifier will flag some issues with the mail.jar file and this works around that issue.
o -synonym: creates public synonyms for these classes. Since we will not install the mail java code we write as SYS, this allows us to 'see' the SYS loaded java classes.
o -g public: grants execute on these loaded classes to PUBLIC. If this is not desirable, change the ?g to be just the user you want to create the 'send mail' routines in, for example -g UTILITY_ACCT.
You can find out more about loadjava and the above options in the Oracle8I Java Developers Guide.

After these packages are loaded, we are ready to create a Java stored procedure to actually send the mail. This procedure will act as a thin layer on top of the JavaMail API and will let us ultimately write a PL/SQL binding layer with the following spec:

tkyte@TKYTE816> desc send
FUNCTION send RETURNS NUMBER
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 P_FROM                         VARCHAR2                IN
 P_TO                           VARCHAR2                IN
 P_CC                           VARCHAR2                IN
 P_BCC                          VARCHAR2                IN
 P_SUBJECT                      VARCHAR2                IN
 P_BODY                         VARCHAR2                IN
 P_SMTP_HOST                    VARCHAR2                IN
 P_ATTACHMENT_DATA              BLOB                    IN
 P_ATTACHMENT_TYPE              VARCHAR2                IN
 P_ATTACHMENT_FILE_NAME         VARCHAR2                IN

This function will give us the ability to use CC's and BCC's and send an attachment. It is left as an exercise for the reader to implement passing arrays of BLOBs or overloading this to support CLOB or BFILE types for attachments as well.

The Java stored procedure we will create follows. It uses the basic functionality of the JavaMail API class and is relatively straightforward. Again, we are not going into all of the uses of the JavaMail API (that could be a book in itself), just the basics here.  The ?mail? class below has a single method ?send?.  This is the method we will use to send a message.  As it is implemented, it returns the number 1 if it is successful in sending the meial and a 0 otherwise.  This implementation is very basic ? it could be much more sophisticated, providing support for many attachment types (CLOBS, BFILES, LONGS and so on).  It could also be modified to report back to the caller the exact error received from SMTP such as ?invalid recipient, no transport, and so on.


tkyte@TKYTE816> create or replace and compile
  2  java source named "mail"
  3  as
  4  import java.io.*;
  5  import java.sql.*;
  6  import java.util.Properties;
  7  import java.util.Date;
  8  import javax.activation.*;
  9  import javax.mail.*;
 10  import javax.mail.internet.*;
 11  import oracle.jdbc.driver.*;
 12  import oracle.sql.*;
 13
 14  public class mail
 15  {
 16    static String dftMime = "application/octet-stream";
 17    static String dftName = "filename.dat";
 18
 19    public static oracle.sql.NUMBER
 20                         send(String from,
 21                              String to,
 22                              String cc,
 23                              String bcc,
 24                              String subject,
 25                              String body,
 26                              String SMTPHost,
 27                              oracle.sql.BLOB attachmentData,
 28                              String attachmentType,
 29                              String attachmentFileName)

The above argument list matches up with the SQL call specification we outlined above ? the arguments are mostly self explanatory.  The two that might need some clarification are the attachmentType and the attachmentFileName.  The attachmentType should be a MIME (Multi-purpose Internet Mail Extensions) type ? as you might be familiar with from HTML documents.  The MIME type of a GIF image for example is ?image/gif?, the mime type of a plain text document would be ?text/plain?, an HTML attachment would be ?text/html? and so on.  The attachmentFileName in this example is NOT the name of an existing OS file that would be attached but rather the filename of the attachment in the email itself ? what the recipient of this email will see the name of the attachment as.  The actual attachment is the oracle.sql.BLOB that is sent to this routine.  Now, onto the body of the code.  We begin by setting the session property ?mail.smtp.host? to the name of the SMTP host the caller sent to us ? the JavaMail API reads this value when deciding what SMTP server to connect to:

 30    {
 31      int rc = 0;
 32
 33      try
 34      {
 35        Properties props = System.getProperties();
 36        props.put("mail.smtp.host", SMTPHost);
 37        Message msg =
 38          new MimeMessage(Session.getDefaultInstance(props, null));
 39

Next, we set up the email headers.  This part tells the JavaMail API who the message if from, who to send it to, who to send a ?carbon copy? (cc) or ?blind carbon copy? (bcc), what the subject of the email is and what date should be associated with the email:

 40       msg.setFrom(new InternetAddress(from));
 41
 42       if (to != null && to.length() > 0)
 43          msg.setRecipients(Message.RecipientType.TO,
 44                            InternetAddress.parse(to, false));
 45
 46       if (cc != null && cc.length() > 0)
 47          msg.setRecipients(Message.RecipientType.CC,
 48                            InternetAddress.parse(cc, false));
 49
 50       if (bcc != null && bcc.length() > 0)
 51          msg.setRecipients(Message.RecipientType.BCC,
 52                            InternetAddress.parse(bcc, false));
 53
 54       if ( subject != null && subject.length() > 0 )
 55            msg.setSubject(subject);
 56       else msg.setSubject("(no subject)");
 57
 58        msg.setSentDate(new Date());
 59

Next, we use one of two methods to send an email.  If the attachmentData argument is not null, then we will MIME encode the email ? a standard that supports the sending of attachments and other multi-part documents.  We do this by setting up multiple MIME body parts ? in this case two of them, one for the body of the email (the text) and the other for the attachment itself.  Lines 76 through 78 need a little additional explanation.  They are how we can send an email via a BLOB.  The JavaMail API doesn?t understand the oracle.sql.BLOB type natively (it is after all a generic API).  In order to send the BLOB attachment, we must provide a method for the JavaMail API to get at the BLOB data.  We accomplish that by creating our own DataHandler ? a class with an interface that the JavaMail API understands how to call in order to get data to populate the attachment.  This class (BLOBDataHandler) is implemented by us as a nested class below.

 60        if (attachmentData != null)
 61        {
 62          MimeBodyPart mbp1 = new MimeBodyPart();
 63          mbp1.setText((body != null ? body : ""));
 64          mbp1.setDisposition(Part.INLINE);
 65
 66          MimeBodyPart mbp2 = new MimeBodyPart();
 67          String type =
 68              (attachmentType != null ? attachmentType : dftMime);
 69
 70          String fileName = (attachmentFileName != null ?
 71                             attachmentFileName : dftName);
 72
 73          mbp2.setDisposition(Part.ATTACHMENT);
 74          mbp2.setFileName(fileName);
 75
 76          mbp2.setDataHandler(new
 77             DataHandler(new BLOBDataSource(attachmentData, type))
 78          );
 79
 80          MimeMultipart mp = new MimeMultipart();
 81          mp.addBodyPart(mbp1);
 82          mp.addBodyPart(mbp2);
 83          msg.setContent(mp);
 84        }

If the email does not have an attachment ? setting the body of the email is accomplished very simply via the single call to setText:

 85        else
 86        {
 87          msg.setText((body != null ? body : ""));
 88        }
 89        Transport.send(msg);
 90        rc = 1;
 91      } catch (Exception e)
 92      {
 93        e.printStackTrace();
 94        rc = 0;
 95      } finally
 96      {
 97        return new oracle.sql.NUMBER(rc);
 98      }
 99    }
100

Now for our nested class BLOBDataSource.  It simply provides a generic interface for the JavaMail API to access our oracle.sql.BLOB type.  It is very straightforward in its implementation:

101    // Nested class that implements a DataSource.
102    static class BLOBDataSource implements DataSource
103    {
104      private BLOB   data;
105      private String type;
106
107      BLOBDataSource(BLOB data, String type)
108      {
109          this.type = type;
110          this.data = data;
111      }
112
113      public InputStream getInputStream() throws IOException
114      {
115        try
116        {
117          if(data == null)
118            throw new IOException("No data.");
119
120          return data.getBinaryStream();
121        } catch(SQLException e)
122        {
123          throw new
124          IOException("Cannot get binary input stream from BLOB.");
125        }
126      }
127
128      public OutputStream getOutputStream() throws IOException
129      {
130        throw new IOException("Cannot do this.");
131      }
132
133      public String getContentType()
134      {
135        return type;
136      }
137
138      public String getName()
139      {
140        return "BLOBDataSource";
141      }
142    }
143  }
144  /

Java created.

Now that we have the Java class created for PL/SQL to bind to, we need to create that binding routine to map the PL/SQL types to their Java Types and to bind the PL/SQL routine to this Java class. That is simply:

tkyte@TKYTE816> create or replace function send(
  2      p_from                  in varchar2,
  3      p_to                    in varchar2,
  4      p_cc                    in varchar2,
  5      p_bcc                   in varchar2,
  6      p_subject               in varchar2,
  7      p_body                  in varchar2,
  8      p_smtp_host             in varchar2,
  9      p_attachment_data       in blob,
 10      p_attachment_type       in varchar2,
 11      p_attachment_file_name  in varchar2) return number
 12  as
 13  language java name 'mail.send( java.lang.String,
 14                                 java.lang.String,
 15                                 java.lang.String,
 16                                 java.lang.String,
 17                                 java.lang.String,
 18                                 java.lang.String,
 19                                 java.lang.String,
 20                                 oracle.sql.BLOB,
 21                                 java.lang.String,
 22                                 java.lang.String
 23                               ) return oracle.sql.NUMBER';
 24  /

Function created.

Now, the very last thing we must do before using this is to ensure our user (the owner of the above "mail" class and "send" stored procedure) has sufficient privileges to execute the routine. Those would be the following:

sys@TKYTE816> begin
  2    dbms_java.grant_permission(
  3       grantee => 'TKYTE',
  4       permission_type => 'java.util.PropertyPermission',
  5       permission_name => '*',
  6       permission_action => 'read,write'
  7    );
  8    dbms_java.grant_permission(
  9       grantee => 'TKYTE',
 10       permission_type => 'java.net.SocketPermission',
 11       permission_name => '*',
 12       permission_action => 'connect,resolve'
 13    );
 14  end;
 15  /

PL/SQL procedure successfully completed.

Note that in the grant on java.net.SocketPermission, I used a wildcard in the permission_name. This allows TKYTE to connect to and resolve ANY host. Technically, we could put in there just the name of the SMTP sever we will be using.  That would be the minimal grant we needed. This is needed in order to resolve the hostname of our SMTP host and then connect to it.  The other permission, java.util.PropertyPermission, is needed in order to set the mail.smtp.host in our sessions properties.

Now we are ready to test. I reused some code from the DBMS_LOB section where we had a routine "load_a_file". I modified that and the DEMO table to have a BLOB column instead of a CLOB and loaded the mail8i.zip file we loaded in as a class into this demo table. Now I can use the following PL/SQL block to send it to myself as an attachment in an email from the database:

tkyte@TKYTE816> set serveroutput on size 1000000
tkyte@TKYTE816> exec dbms_java.set_output( 1000000 )

tkyte@TKYTE816> declare
  2    ret_code number;
  3  begin
  4    for i in (select theBlob from demo )
  5    loop
  6      ret_code := send(
  7                    p_from => 'tkyte@oracle.com',
  8                    p_to => 'tkyte@oracle.com',
  9                    p_cc => NULL,
 10                    p_bcc => NULL,
 11                    p_subject => 'Use the attached Zip file',
 12                    p_body => 'to send email with attachments....',
 13                    p_smtp_host => 'aria.us.oracle.com',
 14                    p_attachment_data => i.theBlob,
 15                    p_attachment_type => 'application/winzip',
 16                    p_attachment_file_name => 'mail8i.zip');
 17      if ret_code = 1 then
 18        dbms_output.put_line ('Successfully sent message...');
 19      else
 20        dbms_output.put_line ('Failed to send message...');
 21      end if;
 22    end loop;
 23  end;
 24  /
Successfully sent message...

PL/SQL procedure successfully completed.

You definitely want to set serverouput on and call the DBMS_JAVA.SET_OUTPUT routine on when testing this. This is because the exception is being printed by the Java stored procedure to System.out and by default that will go into a trace file on the server. If you want to see any errors in your SQLPlus session, you need to make these two settings. It will be very useful for debugging purposes!

<b>Summary</b>

In this section, we briefly reviewed the existing UTL_SMTP package.  Here we saw how to send emails to multiple recipients with a custom From: and Subject: header.  That should satisfy most peoples needs for sending email from the 
>

Rating

  (415 ratings)

Comments are currently disabled for this question.

Comments

Very Good but a small doubt

Srinivas, March 29, 2001 - 5:47 am UTC

How do i send the mails thru oracle 7.1 database as ourt dataBase is not Oracle 8. can u plz send me ur suggestion...will the same solution work for Oracle 7.1???


Great Solution for Email sending from within Database

Bijay R. Tuladhar, April 09, 2001 - 2:39 pm UTC

This is one of the most useful solutions.
Thank you Tom for helping us all!

E-Mail

Gopal KVS, April 12, 2001 - 6:40 am UTC

Excelent, but sending mails has been discussed, how about receiving mails.

Bhagat Singh, June 11, 2001 - 11:03 pm UTC


jar files

Shawn, July 09, 2001 - 10:21 pm UTC

I tried to un-jar them and re-jar the files. while using loadjava I am getting a java.util exception.
Any suggestions? Or can you send me the re-jar'ed files and tell me where to get them.

Thanks,

I run until step 3, error occurs, can not continue...

yong@airmedia.com, July 12, 2001 - 4:05 pm UTC

The error message is :
$ loadjava -u user/paswd@db -o -r -f -v mail.java
initialization complete
loading : mail
creating : mail
resolver :
resolving: mail
errors : mail
ORA-29535: source requires recompilation
mail:31: Class Message not found.
mail:31: Class MimeMessage not found.
mail:37: Variable msg may not have been initialized.
mail:39: Variable msg may not have been initialized.
mail:41: Variable msg may not have been initialized.
mail:44: Undefined variable or class name: Transport
Info: 6 errors
loadjava: 8 errors

Can anyone help me out? Thanks in advance.


Rajesh Jaswal, July 24, 2001 - 11:44 am UTC

Very good solution.

Excellently simplified solution

Akthar &amp; Kamalanathan - akthar.aj@ebridgex.com, July 26, 2001 - 5:52 am UTC

Neatly done with correct step, We would like to comment(checklist) something on positive sense ,
1. First to start with Check whether JVM for Oracle is installed, else run $oracle_home/javavm/install/initjvm.sql
2.Set(add) classpath $oracle_home/sqlj/lib/translator.zip
3.Follow the steps 1,2,3,4 given in the TOM's response with only change on step 4 you have to "desc send" not "desc mail". Step 5 make changes to suit your SMTP HOST.
4. You are done ...

Wish u Happy Oracle Mailing on 8.1.5.




Mail-trouble

Vera, October 25, 2001 - 1:11 am UTC

Don't you think that in the sentence loadjava parameter -s (synonym) for activation8i.jar and mail8i.jar elso must be present ?

Kiro, December 28, 2001 - 10:11 am UTC

It is good but how to attach file to my e-mail?

Having problem in stage 3

Kazi Nazmul Hassan, January 26, 2002 - 10:25 pm UTC

Dears,
When running on step 3 i got the following errors.
Can anyone help me out of it?

D:\mail>loadjava -u marchant/marchant@itcmis -o -r -f -v mail.java
arguments: '-u' 'marchant/marchant@itcmis' '-o' '-r' '-f' '-v' 'mail.java'
creating : source mail
loading : source mail
creating : mail
resolving: source mail
errors : source mail
ORA-29535: source requires recompilation
mail:31: Class Message not found.
mail:31: Class MimeMessage not found.
mail:37: Variable msg may not have been initialized.
mail:39: Variable msg may not have been initialized.
mail:41: Variable msg may not have been initialized.
mail:44: Undefined variable or class name: Transport
Info: 6 errors
The following operations failed
source mail: resolution
exiting : Failures occurred during processing

Thanks

Tom Kyte
January 27, 2002 - 10:26 am UTC

use NOVERIFY as well.

On Januarary 27th, 2002 -- I totally rewrote the answer to this. The answer above is now an extract from my book which has better step by steps..... Follow those.

getting error

Arindam Kar, January 27, 2002 - 3:08 am UTC

HI all

While loading Jar files I am getting the following error, can any body tell me why??
loadjava -u sys/change_on_install -o -r -
v -g public activation8i.jar java.lang.NoClassDefFoundError: oracle/jdbc/driver/OracleDriver
at oracle.aurora.server.tools.LoadJava.getConnection(LoadJava.java:526)
at oracle.aurora.server.tools.LoadJava.fileIsDifferent(LoadJava.java:442
)
at oracle.aurora.server.tools.LoadJava.loadAndCreateJar(LoadJava.java:93
1)
at oracle.aurora.server.tools.LoadJava.processLoadAndCreate(LoadJava.jav
a:1149)
at oracle.aurora.server.tools.LoadJava.process(LoadJava.java:1021)
at oracle.aurora.server.tools.LoadJavaMain.run(LoadJavaMain.java:193)
at oracle.aurora.server.tools.LoadJavaMain.main(LoadJavaMain.java:49)



Can I send email from D2K?

Sazzadur Rahman Tusar, January 28, 2002 - 11:07 pm UTC

I tried to send email from D2K but it failed.
I used OLE2.OBJ_TYPE as per your writings earlier, but it shows error, because OBJ_TYPE is not a procedure.
How it will be solved?
Would you please give me a solution?

I have something missing...??

Yogeeraj, January 31, 2002 - 4:57 am UTC

hi,
I tried the first example, it does not seem to work. Any Idea?
thanks in advance
Yogeeraj
========================================
SQL> begin
send_mail( 'ydegambur@cmt.mu',
'ydegambur@cmt.mu',
'Hello Deg' );
end;
/  2    3    4    5    6
begin
*
ERROR at line 1:
ORA-20001: 421 Service not available
ORA-06512: at "SYS.UTL_SMTP", line 83
ORA-06512: at "SYS.UTL_SMTP", line 121
ORA-06512: at "SW.SEND_MAIL", line 8
ORA-06512: at line 2

SQL>
============================================== 

Tom Kyte
January 31, 2002 - 7:15 am UTC

you did not use a valid mail host in your send_mail routine. You are getting an error back from the "smtp" server (which isn't an smtp server) saying "i'm not available"

you did change:

5 as
6 l_mailhost VARCHAR2(255) := 'aria.us.oracle.com';
7 l_mail_conn utl_smtp.connection;
8 BEGIN

to have a hostname that would be valid for you right?



Great it works!!

Yogeeraj, February 01, 2002 - 6:40 am UTC

Hi,

thanks for locating the error for me. Indeed, there was an error in the address.

sorry for any inconveniences.
;)

For sure, this will help me proceed in my implementations and research.

Best Regards
Yogeeraj

TOM you are simply GREAT..!!!!!

Manoj Bajaj, February 18, 2002 - 9:33 pm UTC

Tom this mail routine we are using it since last few months and is running and mailing well. thank u so much.

I have made some changes to this routine to send multiple files / attachments ..ofcourse by not passing blob array ..(as did not know I to do that ..!!!) but by reading files in java program..! I would like to send u the source.

Mean I would also like to know one thing what decides total attachment size to be sent in one mail. In one database sch I can send attachments of 1MB whereas in other I'm restricted to 6 MB..I'm cannot find what is restricting me from sending bigger attachments...Any clue...unix or oracle parameter as these two are on diff unix servers but SMTP is same.

Once again Many thanks for ur continuous support.

Error handling

Sudip Sarkar, February 21, 2002 - 10:01 am UTC

Hi Thomas,
Your solutions are simply great. I have used your code to send email. But I facing a peculiar problem. Once there was a problem in the SMTP server and it stopped responding, now at that moment I fired a mail from the database. The result was that my sesion got hung.
Is there any way of trapping the error.

manoj, February 25, 2002 - 12:46 am UTC

Hi Check the trace file generated in user_dump_dest ..directory on your server u may get the exacty nature of problem there.

Looks promising, but am having problems installing - loadjava fails

Bob Yexley, February 25, 2002 - 1:40 pm UTC

Thanks so much for this solution. If I can get it working, it will be a HUGE help and solution for our needs.

I am trying to follow the instructions laid out here, and did everything they said to do, but am having problems with the loadjava command for mail8i.zip. When I ran it, it loaded everything fine, but ran into problems when trying to resolve referenced objects. I'm getting ORA-29534, and the result is 45 unresolved object references after the load. The loading of the activation8i.zip worked great, no problems at all, but had problems with SOME of the objects in mail8i.zip. Here is one example of the errors that I am getting:

==========================================================
skipping : com/sun/mail/imap/Rights$Right is already resolved
skipping : javax/mail/IllegalWriteException is already resolved
skipping : com/sun/mail/iap/Argument is already resolved
resolving: com/sun/mail/smtp/SMTPMessage
errors : com/sun/mail/smtp/SMTPMessage
ORA-29534: referenced object SYS.javax/mail/internet/MimeMessage could not be resolved
resolving: javax/mail/internet/MimeMessage
errors : javax/mail/internet/MimeMessage
ORA-29521: referenced name javax/activation/DataHandler could not be found
ORA-29521: referenced name javax/activation/DataSource could not be found
resolving: javax/mail/FolderClosedException
errors : javax/mail/FolderClosedException
ORA-29534: referenced object SYS.javax/mail/Folder could not be resolved
==========================================================

Any idea what's wrong, and/or how I can fix it??

-::YEX::-
<)))><


Tom Kyte
February 25, 2002 - 2:13 pm UTC

show me a cut and paste of your loadjava command.

Response to followup

Bob Yexley, February 26, 2002 - 1:24 pm UTC

My loadjava command was as follows:

C:\MyDir>loadjava -u sys/password@orcl -o -r -v -f -noverify -synonym -g public mail8i.zip

Tom Kyte
February 26, 2002 - 5:14 pm UTC

Can you reload both the activation and mail ZIP files using another user? This will facilitate debugging and we can use it to check the resolver for any problems. Also, add '-debug' to your loadjava commands and send that output to mbpierma@us.oracle.com.

Some problem! can anyone help

Raza, February 26, 2002 - 1:39 pm UTC

I was trying tom's example 1 and have this error! can any one help me out
begin
mail_pkg.send
( p_sender_email => 'rkazmi@rci.rogers.com',
p_from => 'Oracle Database Account <rkazmi@rci.rogers.com>',
p_to => mail_pkg.array( 'kazmi81@hotmail.com',
'kazmi@rogers.com' ),
p_cc => mail_pkg.array( 'kazmi5221@rogers.com' ),
p_bcc => mail_pkg.array( 'utility@aria.us.oracle.com' ),
p_subject => 'This is a subject',
p_body => 'Hello Raza, this is the mail you need' );
end;

ORA-29540: class oracle/plsql/net/TCPConnection does not exist
ORA-06512: at "SYS.UTL_TCP", line 678
ORA-06512: at "SYS.UTL_TCP", line 247
ORA-06512: at "SYS.UTL_SMTP", line 99
ORA-06512: at "SYS.UTL_SMTP", line 121
ORA-06512: at "SYS.MAIL_PKG", line 49
ORA-06512: at line 2

and what needs to be done!!!???

Tom Kyte
February 26, 2002 - 2:32 pm UTC

search for

ORA-29540

on this site.

Another problem!!

Raza, February 26, 2002 - 3:29 pm UTC

After issuing the following command
(RCIS_DEV)$ loadjava -user sys/change_on_install@rcis_dvl plsql.jar

I got this error!!

SQL Error while connecting with oci8 driver to rcis_dvl: ORA-01031: insufficient
privileges

could not open connection
loadjava: 2 errors

Tom Kyte
February 26, 2002 - 4:46 pm UTC

this should not be done over the network -- the file you are loading must be the one on the server anyway so... don't use the network.

Sending e-mail! -- Oracle 8i specific response

Harvey, February 26, 2002 - 4:03 pm UTC

Do we need to do the same things for Oracle9i as you described in this detailed instruction? If it is different, could you explain it also in detail?

Thanks a lot!

Harvey

Tom Kyte
February 26, 2002 - 4:49 pm UTC

should work in 9i, haven't loaded it up myself as yet but the steps would basically be the same (you don't have to use sys and probably won't be able to use sys in most cases in 9i, that would be different)

yes, you would need to do this in 9i if you wanted to send email with attachments.

Implemented the SMTP mail sending attachments pure Oracle code

Ashokkumar Sankaran, February 26, 2002 - 5:43 pm UTC

Thx for your Valuable ideas

We have succefully implmented the SMTP mail with any attachments Including Binary in Pure oracle code

(i .e It Converts Binary to Base 64 format)

Thx
Ashok

Problem using loadjava

A reader, February 27, 2002 - 9:58 am UTC

I cant get it work!

I have two instances running on the same machine,
I have opened the telnet session on box where my database is, and trying to load plsql.jar by issuing the following command.
(RCIS_DEV)$ loadjava -user sys/change_on_install@rcis_dvl plsql.jar
And getting this error..

SQL Error while connecting with oci8 driver to rcis_dvl: ORA-01031: insufficient
privileges

could not open connection
loadjava: 2 errors

I checked my $ORACLE_SID which is set to rcis_dvl
and if I issue loadjava without @rcis_dvl
(RCIS_DEV)$ loadjava -user sys/change_on_install plsql.jar

Then I get this error!!

SQL Error while connecting with oci8 driver to default database: ORA-01034: ORAC
LE not available
ORA-27101: shared memory realm does not exist
IBM AIX RISC System/6000 Error: 2: No such file or directory

could not open connection
loadjava: 2 errors
What should be done!!! you advice
Thanks in advance
Raza

Tom Kyte
February 27, 2002 - 10:44 am UTC

You should log in as the Oracle software owner.

You should verify your oracle_home and oracle_sid

You should verify that you can then:

sqlplus sys/change_on_install


then run loadjava.

xue li, March 01, 2002 - 8:57 am UTC

Very nice!

But where can i get more information about UTL_SMTP.

Tom Kyte
March 01, 2002 - 9:12 am UTC

all supplied packages are documented in the supplied packages guide

</code> http://docs.oracle.com/docs/cd/A87860_01/doc/appdev.817/a76936/utl_smtp.htm#1000695 <code>
....

BCC List

Chris Soza, April 03, 2002 - 11:25 am UTC

Tom,

In your pl/sql solution if bcc list is not written out with writeData, can you explain how it will work ?

Thanks,

Chris

Tom Kyte
April 03, 2002 - 4:03 pm UTC

because this:

15 utl_smtp.rcpt(g_mail_conn, p_recipients(i) );



does the actual sending, the writing of the CC and TO list is only for display -- the call to writedata with that doesn't affect WHO the email is actually sent to -- just what the email client displays.

Partly

Sandeep Pathak, April 04, 2002 - 2:23 am UTC

I have followed all the instructions. And they were successfull also. But when I type the following command

SQL> desc send
ERROR:
ORA-04043: object send does not exist

I get the above said error.
Can anybody help me.
The mail8i and activation8i, are proper. But if anybody has a working version please send on sandeep@inbox.net 

Tom Kyte
April 04, 2002 - 11:44 am UTC

If you run this:

tkyte@TKYTE816> create or replace function send(
2 p_from in varchar2,
3 p_to in varchar2,
4 p_cc in varchar2,
5 p_bcc in varchar2,
6 p_subject in varchar2,
7 p_body in varchar2,
8 p_smtp_host in varchar2,
9 p_attachment_data in blob,
10 p_attachment_type in varchar2,
11 p_attachment_file_name in varchar2) return number
12 as
13 language java name 'mail.send( java.lang.String,
14 java.lang.String,
15 java.lang.String,
16 java.lang.String,
17 java.lang.String,
18 java.lang.String,
19 java.lang.String,
20 oracle.sql.BLOB,
21 java.lang.String,
22 java.lang.String
23 ) return oracle.sql.NUMBER';
24 /

Function created.



(which is above, in the answer), you will not get that response. Me thinks you skipped a step or two.



mail.jar and activation.jar

Chris Soza, April 04, 2002 - 9:31 am UTC

Tom

I downloaded the javamail package as per your note. However, in the archive there is no activation.jar file. Any idea how I can get this ?. I downloaded the 1.2 version.

Also, thanks for explaining how bcc list works.

Rgds, Chris

Tom Kyte
April 04, 2002 - 1:03 pm UTC

It is separate, goto java.sun.com and search for activation.

error

nagarju, April 04, 2002 - 12:27 pm UTC

tom,

i run the following snippet of code, i get the error

declare
l_mailhost VARCHAR2(255) := 'our mailserver ip';
l_mail_conn utl_smtp.connection;
begin
l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
utl_smtp.helo(l_mail_conn, l_mailhost);
utl_smtp.mail(l_mail_conn, 'nagarjuk@yahoo.com');
utl_smtp.rcpt(l_mail_conn, 'nagarajuk@hotmail.com');
utl_smtp.open_data(l_mail_conn );
utl_smtp.write_data(l_mail_conn, 'pakka ma');
utl_smtp.close_data(l_mail_conn );
utl_smtp.quit(l_mail_conn);
end;

ORA-20002: 550 5.7.1 Unable to relay for nagarajuk@hotmail.com
ORA-06512: at "SYS.UTL_SMTP", line 86
ORA-06512: at "SYS.UTL_SMTP", line 223
ORA-06512: at line 8

can you tell me why is this?
i get this error what ever the email address i give in the recpt

please help

Tom Kyte
April 04, 2002 - 1:23 pm UTC

contact your email guys/network guys.

the server you are attempting to use is not set up to relay, this is NOT an oracle issue, not a UTL_SMTP issue, it is a SMTP configuration issue. You are probably using the WRONG mailhost as it's not setup to relay (anti-spamming defense)

email body size

manohar, April 04, 2002 - 3:43 pm UTC

tom,

is there a limit on the email body size like you mentioned in your answer as 32k only.

please reply.

thanks

Tom Kyte
April 04, 2002 - 3:57 pm UTC

Only as I have it coded. I am passing the body as a single plsql varchar2 variable.

If you passed a temporary clob and wrote it out 32k at a time, you could make it as large as you wanted. There is no limit (well, 4gig)

sending multiple emails in a single SP

nagaraju, April 04, 2002 - 5:20 pm UTC

If i have to send multiple emails,like typicallly.

i have a cursor that returns email addresses and other detials. i need to loop and email the other details to the email address

is it only the following way or anyother simple way

declare
l_mailhost VARCHAR2(255) := 'our mail server';
l_mail_conn utl_smtp.connection;
g_crlf char(2) default chr(13)||chr(10);
begin
l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
utl_smtp.helo(l_mail_conn, l_mailhost);
for rec in c_email_cur
loop
utl_smtp.mail(l_mail_conn, 'nagarajuk@hotmail.com');
utl_smtp.rcpt(l_mail_conn, rec.email_address);
utl_smtp.open_data(l_mail_conn );
utl_smtp.write_data( l_mail_conn, 'Date: ' || sysdate || g_crlf );
utl_smtp.write_data( l_mail_conn, 'Subject: ' || 'Testing utl_smtp' || g_crlf );
utl_smtp.write_data(l_mail_conn,'To: ' || rec.email_address || g_crlf);
utl_smtp.write_data(l_mail_conn, 'This is a Reminder for a Notification Received originally on: March 1, 2002.'|| g_crlf);
utl_smtp.write_data(l_mail_conn, g_crlf);
utl_smtp.write_data(l_mail_conn, 'The Access Removal form attached requires your immediate attention. '||rec.somevalue || g_crlf);
utl_smtp.write_data(l_mail_conn, g_crlf);
utl_smtp.write_data(l_mail_conn, 'Access Removal Request For:'|| g_crlf);
utl_smtp.write_data(l_mail_conn, g_crlf);
utl_smtp.close_data(l_mail_conn );
end loop;
utl_smtp.quit(l_mail_conn);
end;

any suggestions?

thanks

Tom Kyte
April 04, 2002 - 7:19 pm UTC

Yes, use modular code and factor out repeated processing

Write a send_mail routine (or just use the ones above).

then it becomes:

begin
for rec in ( select ... )
loop
send( .... );
end loop;
end;
/

Thats what procedures are all about.

Attaching a bfile

Johan Snyman, April 09, 2002 - 5:11 am UTC

Can you please indicate how the code need to be changed to e-mail a bfile as an attachment (I have to e-mail compressed files in an OS filesystem).

I am just starting to learn Java and don't even know where to start with above mentioned problem (although I expect at least the BLOBDataSource nested class to change or a similar class for bfile to be added).

By the way - which resources would you suggest for learning Java, coming from an Oracle background ?

Tom Kyte
April 09, 2002 - 7:56 am UTC

Should be as easy as changing p_attachment_type to BFILE and opening the BFILE in plsql before calling java -- the api for reading a bfile in java is the same as a blob.

You might consider:

</code> http://www.amazon.com/exec/obidos/ASIN/1861006020/ <code>

it has some nifty utilities in it. It is written for the PLSQL developer that wants to get their feet wet with some java.

Email from database

Randy Richardson, April 10, 2002 - 9:44 am UTC

Tom,

Is there a way to validate the TO list before sending? Or do you have to just send and let the bad email addresses fail? We are using MS exchange 2000 mail server and would like to do validation against the address book.

Thanks.



Tom Kyte
April 10, 2002 - 10:22 am UTC

Well, the email is coming from the database (on the server)

The address book is in exchange or on the client...


If you can ask MS how to access the address book via java, we can certainly do that. (hmm, isn't this how email viruses get started?)

I'm doubtful, all kinds of security issues with accessing the address book (you have to "trust" the oracle account) and I don't know if Java can access that or not. We could use C as well if they support that -- but the security issues abound.

java option in oracle

srividhya, April 15, 2002 - 2:58 am UTC

Hi Tom,

Thanks a lot for the mail.It is really great and working fine.We had installed on the development database(oracle 8.1.6) and had no problems with it. However, when we tried to deploy on our live database(oracle 8.1.6), we are facing a lot of installation problems. We realized that the java option has not been set when the database was setup(1.5 years ago).The database size is 25GB.How do we set the java option?We are not able to set the java option as an incremental update.How do we do that.
Thanks in advance.
Please reply...!!. We are just held up in deploying it.


Tom Kyte
April 16, 2002 - 7:01 am UTC

Have you run initjvm.sql found in $ORACLE_HOME/javavm/install

Failure tracking from Oracle

rajiv, April 18, 2002 - 12:01 pm UTC

tom,

is it possible to track the failure of an email.

assume that i am sending email using utl_smtp with TO list has one person and CC list has 10 persons.
now email was sent to all the CC people but not to the TO list person.

in this case i need to send an email to an ADMIN saying email to that TO person is failed

is it possible?

Tom Kyte
April 18, 2002 - 12:24 pm UTC

the email will bounce tot he REPLY-TO address. set the reply-to to admin. I believe there is an "error-to" or something like that as well. you would have to look it up somewhere....

Failure tracking from Oracle

rajiv, April 22, 2002 - 11:35 am UTC

tom,

can you give me how do set the reply-to address to admin.
because when i tried in the following way mail is not sent to the admin. but the bounced mail come to the from addressee only.

declare
l_mailhost VARCHAR2(255) := 'our mail server';
l_mail_conn utl_smtp.connection;
l_toaddr varchar2(50) := 'xyz@xyz.com'; -- invalid email id
l_fromaddr varchar2(50); -- assign the from address here
l_replyto varchar2(50);
g_crlf char(2) default chr(13)||chr(10);
begin
l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
utl_smtp.helo(l_mail_conn, l_mailhost);
utl_smtp.mail(l_mail_conn, l_fromaddr);
utl_smtp.rcpt(l_mail_conn, l_toaddr);
utl_smtp.open_data(l_mail_conn );
utl_smtp.write_data( l_mail_conn, 'Date: ' || sysdate || g_crlf );
utl_smtp.write_data( l_mail_conn, 'Subject: ' || 'Testing utl_smtp' || g_crlf );
utl_smtp.write_data(l_mail_conn,'To: ' || l_toaddr || g_crlf);
utl_smtp.write_data(l_mail_conn,'REPLY-TO: ' || l_replyto || g_crlf);
utl_smtp.write_data(l_mail_conn, 'This is a Reminder for a Notification Received originally on: March 1, 2002.'|| g_crlf);
utl_smtp.write_data(l_mail_conn, g_crlf);
utl_smtp.write_data(l_mail_conn, 'The Access Removal form attached requires your immediate attention. ' || g_crlf);
utl_smtp.write_data(l_mail_conn, g_crlf);
utl_smtp.write_data(l_mail_conn, 'Access Removal Request For:'|| g_crlf);
utl_smtp.write_data(l_mail_conn, g_crlf);
utl_smtp.close_data(l_mail_conn );
utl_smtp.quit(l_mail_conn);
end;

good but have error in downloading mail.zip

shamim, April 24, 2002 - 2:22 am UTC

Great Service done my you TOM
Hi Tom Your answer and subsequent followup are very informative. I tried it , activation.zip doenloaded perfectly but I am facing problem in downloading of mail.zip ,It is showing error while recolving objects,
in the same way as Mr.Bob Yexley have. and send the debugged code at mbpierma@us.oracle.com., BUt message comes that this id doed not exist.
So please if he have given some solution to Mr.Bob Yexley problem Forward it to me.


Tom Kyte
April 24, 2002 - 7:23 am UTC

drop the us. from the email address (as should have been indicated in the bounced email, we've stopped using the country specific domain name)

PL/SQL to do email and appointment

Binh Ta, May 03, 2002 - 11:10 am UTC

Hi Tom,
Very helpful indeed. But I can you answer my follow-up question too please: How can one use PL/SQL to create Appointments in Exchange? I've searched practically the whole internet but found nothing. Would really appreciate if you can shedsome light. Many thanks. Binh Ta.

Tom Kyte
May 03, 2002 - 11:47 am UTC

No idea, I know nothing about exchange. We can do com automatation calls from plsql on NT using the "com cartridge".

E-mail

Munz, May 24, 2002 - 9:48 pm UTC

Tom:

Do I understand that if I want to send an email but with a subject line and a message pulled out of the database I can do it with PL/SQL.

I only need to use jAVAMAIL API when I need t osend attachments.

THank you,


Tom Kyte
May 25, 2002 - 9:04 am UTC

You never *need* javamail, you could use utl_smtp 100%.

It is just much much easier with javamail to send attachments, it does the work for you.

UTL_SMTP is sufficient for sending text based email

email

Munz, May 31, 2002 - 10:30 am UTC

Tom:

If you do not want to use named parameters and not cc or bcc anyone in email how do you pass parameters.

I am getting an error when I do:

begin
mail_pkg.send(
'myname@att.com',
null,
mail_pkg.array('myname@att.com'),
mail_pkg.array(' '),
mail_pkg.array(' '),
'This is a subject',
'Hello Tom, this is the mail you need' );

dbms_output.put_line('Message sent to the user successfully');
end;
/

Can't you pass null values to an array.

Thanks,



Tom Kyte
May 31, 2002 - 10:40 am UTC

why don't you want to use named parameters? they are better then positional, you are not calling this from SQL so that is not an issue.

Otherwise, arrange the parameters to suit your needs (but wait, that'll break your other code unless it uses named parameters)

I would recommend you use a named parameter, it is more readable, less ambigous and if someone changes the order on you later -- you are PROTECTED.

You can do this:

begin
mail_pkg.send( 'sender email', 'from', mail_pkg.array('to'),
mail_pkg.array(), mail_pkg.array(),
'subj', 'body' );
end;
/

as well. You are not passing an empty array - you passed an array with some blank strings -- very different. Just pass empty arrays (like I have them defaulted to)



database link

frustrated mailer, June 10, 2002 - 6:03 pm UTC

TCPConnection class is not loaded in database I want to send mail out from, but the classes are loaded in another db behind the firewall that I can access through a db link.

I have tried creating a synonym for UTL_SMTP using the db link. Should this work?

I also tried writing a package that accepts the same inputs send mail does, but just calls send mail across the db link with the same arguments it was called with.

This doesn't work either. I get wrong number or type arguments.

Can you show how you would call UTL_SMTP across a db link from a db that doesn't have the java classes installed?



Tom Kyte
June 11, 2002 - 10:29 am UTC

utl_smtp uses a record. you are probably not defining your connection record using this remote utl_smtp package.


tkyte@TKYTE816> create or replace
2 PROCEDURE send_mail (p_sender IN VARCHAR2,
3 p_recipient IN VARCHAR2,
4 p_message IN VARCHAR2)
5 as
6 l_mailhost VARCHAR2(255) := 'aria.us.oracle.com';
7 l_mail_conn ALIAS_FOR_UTL_SMTP.connection;

but, sigh, without an example and the error message cut and pasted from sqlplus, its really hard to tell

Some details when using UTL_SMTP...

Sven Bleckwedel, June 19, 2002 - 1:36 pm UTC

Hi TOM,

Your explanation was very useful to help me to implement this resource in a database that i administer.  When using another character set (in my case, WE8ISO8859P1) some problems appeared, but i´ve found some tips that helped me to solve this problem, too:

<quote>
The original SMTP protocol communicates using 7-bit ASCII. But if the target SMTP server supports 8BITMIME extension, the user can convert the non-US7ASCII data to RAW and use the write_raw_data procedure to send data using 8-bit MIME 
encoding
...
Using the utl_smtp and utl_tcp packages requires that the JServer option is installed in the database.
Reference: Oracle8i Supplied PL/SQL Packages Reference, 65 UTL_SMTP
<quote>

- The code, before changes:

 61 writeData('Date: ' || l_date);
 62 writeData('From: ' || nvl(p_from, p_sender_email));
 63 writeData('Subject: ' || nvl(p_subject,'(nosubject)'));
 64
 65 writeData( l_to_list );
 66 writeData( l_cc_list );
 67
 68 utl_smtp.write_data(g_mail_conn, '' || g_crlf);
 69 utl_smtp.write_data(g_mail_conn, p_body );
 70 utl_smtp.close_data(g_mail_conn );
 71 utl_smtp.quit(g_mail_conn);

- After changes are made, at lines 65-67 and 72:

 61 writeData('Date: ' || l_date);
 62 writeData('From: ' || nvl(p_from, p_sender_email));
 63 writeData('Subject: ' || nvl(p_subject,'(no subject)'));
 64
 65 utl_smtp.write_data(g_mail_conn,'MIME-Version: 1.0' || g_crlf);
 66 utl_smtp.write_data(g_mail_conn,'Content-Type: text/plain; charset=iso-8859-1' || g_crlf)
 67 utl_smtp.write_data(g_mail_conn,'Content-Transfer-Encoding: 8bit' || g_crlf);
 68
 69 writeData( l_to_list );
 70 writeData( l_cc_list );
 71 
 72 utl_smtp.write_raw_data(g_mail_conn,utl_raw.cast_to_raw(g_crlf || p_body));
 73 utl_smtp.close_data(g_mail_conn );
 74 utl_smtp.quit(g_mail_conn);

- But, other problems appeared:

SQL> @send_mail3

Package created.

Warning: Package Body created with compilation errors.

SQL> show errors
Errors for PACKAGE BODY MAIL_PKG:

LINE/COL ERROR
-------- ---------------------------------------------
72/5     PL/SQL: Statement ignored
72/14    PLS-00302: component 'WRITE_RAW_DATA' must be
                    declared

Searching for the reason, in Metalink:

fact: Oracle Server - Enterprise Edition 8.1.6.1 
fact: PL/SQL 8.1.6 
symptom: Calling utl_smtp.write_raw_data within application 
symptom: Procedure UTL_SMTP.WRITE_RAW_DATA Does Not Exist 
cause: <Bug:1239254> Procedure UTL_SMTP.WRITE_RAW_DATA does not exist 
fix: Apply patch 8.1.6.2 or upgrade to 8.1.7.

After applying the latest patch (8.1.6.3.1, for HP-UX 11.0), the problem was solved !

Sven Bleckwedel
Unix/Oracle Admin
 

Sheryl Smith, June 25, 2002 - 10:57 am UTC

Tom,
When I loadjava
i.e.
loadjava -u sys/passwr -o -r -v -f -noverify -synonyn -g public mail8i.zip

I get the following errors:
resolving: mail/javax/mail/search/ComparisonTerm
Error while resolving class mail/javax/mail/search/ComparisonTerm
ORA-04043: object /fdec8a69_ComparisonTerm does not exist

resolving: mail/com/sun/mail/handlers/message_rfc822
Error while resolving class mail/com/sun/mail/handlers/message_rfc822
ORA-04043: object /83f5d240_message_rfc822 does not exist

resolving: mail/javax/mail/FolderNotFoundException
Error while resolving class mail/javax/mail/FolderNotFoundException
ORA-04043: object /45ac233_FolderNotFoundExcepti does not exist

resolving: mail/com/sun/mail/imap/protocol/BODY
Error while resolving class mail/com/sun/mail/imap/protocol/BODY
ORA-04043: object /a31a955b_BODY does not exist

resolving: mail/javax/mail/search/SentDateTerm
Error while resolving class mail/javax/mail/search/SentDateTerm
ORA-04043: object /70998eaf_SentDateTerm does not exist
.....

What do I need to do?
Thanks.


File system file as attachment

Vikas, June 27, 2002 - 1:50 pm UTC

Hi Tom,
This uses the file stored in the database for attachment. can you pl tell me how to do it for file system. Actually I want to use a browse button for attachments in which user will select file from client os(own system). I am using mod_plsql. Do i need to upload that file in the database and than execute your procedure. or there is any direct apporach. I am wondering how it can be done? Because mod_plsql does not support file system uploads( from client file system to server file system).

Tom Kyte
June 27, 2002 - 2:22 pm UTC

If you want to

a) send email from the server
b) with a file from the client

you'll have to upload the file to the server (mod_plsql will be great for that). Then, it'll be in a blob and the code will work "as is". After you email the document, delete the blob.

I cannot recompile java source mail

Tom Jaros, July 10, 2002 - 4:53 am UTC

I used following way of loadjava:

C:\SourceSafe\frm_rep\mail\JavaMail>loadjava -u sys/gambac12@x -o -r -v -f -synonym -g public mail8i.zip
initialization complete
loading  : mail.jar
creating : mail.jar
resolver :

C:\SourceSafe\frm_rep\mail\JavaMail>loadjava -u sys/gambac12@x -o -r -v -f -synonym -g public activation8i.zip
initialization complete
loading  : activation.jar
creating : activation.jar
resolver :

When I tried to create java source I got the warning message about error in source:
SQL> show error
Errors for JAVA SOURCE mail:

LINE/COL ERROR
-------- -----------------------------------------------------
0/0      mail:98: Interface DataSource of nested class mail.
         BLOBDataSource not found.

0/0      mail:132: Interface DataSource of nested class mail.
         CLOBDataSource not found.

0/0      mail:54: Class Message not found.
0/0      mail:54: Class MimeMessage not found.
0/0      mail:59: Variable msg may not have been initialized.
0/0      mail:61: Variable msg may not have been initialized.
0/0      mail:62: Variable msg may not have been initialized.

LINE/COL ERROR
-------- -----------------------------------------------------
0/0      mail:65: Class MimeBodyPart not found.
0/0      mail:65: Class MimeBodyPart not found.
0/0      mail:68: Class MimeBodyPart not found.
0/0      mail:68: Class MimeBodyPart not found.
0/0      mail:77: Class MimeMultipart not found.
0/0      mail:77: Class MimeMultipart not found.
0/0      mail:86: Undefined variable or class name: Transport
0/0      Info: 14 errors

In database there are only mail.jar and activation.jar, I can see them in SQL Navigator in java resources. What was wrong in loadjava? 

Tom Kyte
July 11, 2002 - 6:59 pm UTC

My name is Mark Piermarini and I work for Tom. He asked me to help you. I have a few questions:

1. Database version?
2. Operating system of the database host?
3. Did you load activation8i.zip before mail8i.zip?
4. Did you get any errors when loading either of the ZIP files? (if so then send those as well).
5. Are any of the classes marked invalid when you look at them with SQL Navigator?
6. What user is running the SQL to create the PL/SQL wrapper and java stored procedure? SYS or another user?
7. Have you tried loading the ZIP and SQL file as another user? (might not work depending upon you database version).

If I recall correctly, there was an issue with the "-g" option for loadjava but i'll have to get your DB version before verifying that as a potential problem.

attached BFILE

kiro, July 29, 2002 - 6:42 am UTC

If someone is interested for attachement of bfile see below:
In Java source I have changed BLOB to BFILE, but as Tom said it can work as it is with BLOB.

create or replace function send_bfile(
p_from in varchar2,
p_to in varchar2,
p_cc in varchar2,
p_bcc in varchar2,
p_subject in varchar2,
p_body in varchar2,
p_smtp_host in varchar2,
p_attachment_data in BFILE,
p_attachment_type in varchar2,
p_attachment_file_name in varchar2) return number
as
language java name 'mail_bfile.send_bfile( java.lang.String,
java.lang.String,
java.lang.String,
java.lang.String,
java.lang.String,
java.lang.String,
java.lang.String,
oracle.sql.BFILE,
java.lang.String,
java.lang.String
) return oracle.sql.NUMBER';



set serveroutput on size 1000000
exec dbms_java.set_output( 1000000 );

declare
ret_code number;
l_bfile bfile := bfilename( 'MY_FILES', 'mail8i.zip' ) ;
begin
dbms_lob.fileopen(l_bfile) ;
ret_code:=send_bfile(
p_from => 'Welcome_From_my_Database',
p_to => 'my@myserv.com',
p_cc => null,
p_bcc => NULL,
p_subject => 'Use the attached Zip file',
p_body => 'to send email with attachments....',
p_smtp_host => 'smtpHOST',
p_attachment_data => l_bfile,
p_attachment_type => 'application/winzip',
p_attachment_file_name => 'mail8i.zip');

if ret_code = 1 then
dbms_output.put_line ('Successfully sent message...');
else
dbms_output.put_line ('Failed to send message...');
end if;
dbms_lob.fileclose( l_bfile ) ;
end;

I have tried on 9i and it is working fine!

Tom
do you have idea how big could be an attached file?
Could you give as a link or info where we can find info about MIME types?
Thanks
kiro

Error trying to run javamail.send function

Richard Smith, August 01, 2002 - 6:06 pm UTC

I successfully executed the pl/sql based mail functions in the article, loaded the JAXF and javamail apis and created the java stored procedure, granted permissions, and created the pl/sql wrapper function. Then when I execute an anonymous block using the same values for from, to, and smtp host as in the utl_smtp examples I get the following error:

javax.mail.NoSuchProviderException: No provider for Address type: rfc822
at javax.mail.Session.getTransport(Session.java:516)
at javax.mail.Transport.send0(Transport.java:155)
at javax.mail.Transport.send(Transport.java:81)
at mail.send(mail:71)
FAILED TO SEND

PL/SQL procedure successfully completed.

Tom Kyte
August 05, 2002 - 9:41 am UTC

do a search for

javax.mail.NoSuchProviderException: No provider for Address type: rfc822

on www.google.com.

......
According to Sun's JavaMail FAQ:

Usually this is because JavaMail can't access the configuration files in mail.jar, possibly because of a security permission problem; see this item for more details. Also, make sure that you haven't extracted the mail.jar contents; you should include the unmodified mail.jar file in the server's CLASSPATH.
.................


It is a java thing, not a database thing here. You might be missing a permission

LoadJava Errors...8.1.7

Sikandar Hayat Awan, August 05, 2002 - 12:41 am UTC

Oracle OEM 8.1.7 on WINNT 4 Sp-5

1/7 >Banner
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
With the Partitioning option
JServer Release 8.1.7.0.0 - Production

2/7 >Error When I am trying to send
ORA-29540: class oracle/plsql/net/TCPConnection does not exist
ORA-06512: at "SYS.UTL_TCP", line 678
ORA-06512: at "SYS.UTL_TCP", line 247
ORA-06512: at "SYS.UTL_SMTP", line 99
ORA-06512: at "SYS.UTL_SMTP", line 121
ORA-06512: at "SYS.MAIL_PKG", line 49
ORA-06512: at line 2
Note: I have configured SMTP email on the same server in OEM and it is working fine.

3/7 >The following statement is successful giving no error
Plsql/jlib
loadjava -user sys/mypass@cstring plsql.jar

4/7 >I have downloaded both files from java-sun-com and performed the steps u mentioned
1. Used WinZip to extract the contents of mail.jar into my c:\temp\mail directory
2. Used WinZip to create a new archive c:\temp\mail8i.zip
3. Put the contents of c:\temp\mail\*.* including subdirectories into this new archive
5/7 >Then issued the following command and received 422 errors if I ommit -g public then 210 errors. I have also changed the user but same result.

D:\Sikandar\Java>loadjava -u sys/mypass -o -r -v -f -noverify -synonym -g public mail8i.zip
The name specified is not recognized as an
internal or external command, operable program or batch file.
initialization complete
loading : mail8i/javax/mail/internet/NewsAddress
creating : mail8i/javax/mail/internet/NewsAddress
loading : mail8i/com/sun/mail/util/QDecoderStream
creating : mail8i/com/sun/mail/util/QDecoderStream
loading : mail8i/com/sun/mail/util/QEncoderStream
creating : mail8i/com/sun/mail/util/QEncoderStream
loading : mail8i/javax/mail/internet/InternetHeaders
creating : mail8i/javax/mail/internet/InternetHeaders
loading : mail8i/com/sun/mail/imap/IMAPFolder$ProtocolCommand
creating : mail8i/com/sun/mail/imap/IMAPFolder$ProtocolCommand
loading : mail8i/com/sun/mail/imap/protocol/Namespaces
creating : mail8i/com/sun/mail/imap/protocol/Namespaces
....
loading : mail8i/com/sun/mail/imap/protocol/BASE64MailboxDecoder
creating : mail8i/com/sun/mail/imap/protocol/BASE64MailboxDecoder
....
loading :
Error while granting to mail8i/com/sun/mail/util/QEncoderStream
ORA-04042: procedure, function, package, or package body does not exist
....
synonym : mail8i/javax/mail/AuthenticationFailedException
loadjava: 422 errors

6/7 >
D:\Sikandar\Java>loadjava -user sys/mypass -o -r -v -f mail.java
The name specified is not recognized as an
internal or external command, operable program or batch file.
internal error: unanticipated exception: java.io.FileNotFoundException: mail.java
java.io.FileNotFoundException: mail.java
at java.io.FileInputStream.<init>(FileInputStream.java:56)
at java.io.FileInputStream.<init>(FileInputStream.java:75)
at oracle.aurora.server.tools.loadjava.LoadJava.processLoadAndCreate(LoadJava.java:1512)
at oracle.aurora.server.tools.loadjava.LoadJava.process(LoadJava.java:1422)
at oracle.aurora.server.tools.loadjava.LoadJavaMain.run(LoadJavaMain.java:299)
at oracle.aurora.server.tools.loadjava.LoadJavaMain.main(LoadJavaMain.java:58)
resolver :
loadjava: 1 errors

**********************************************************
7/7 >In the loadjava help there is no -debug parameter so how to specify it?

"Also, add '-debug' to your loadjava commands and send that output to mbpierma@us.oracle.com."

The following is response from your server,
----- Transcript of session follows -----
... while talking to inet-mail1.oracle.com.:
>>> RCPT To:<mbpierma@us.oracle.com>
<<< 553 5.7.1 <mbpierma@us.oracle.com>... Oracle email addresses in the country-specific format have been retired. Please contact the intended recipient by other means to obtain their correct address. For additional assistance, please contact your local Oracle office representative. 550 5.1.1 <mbpierma@us.oracle.com>... User unknown

Please let me know for any further query.


All Good ..But need to encrypt the attachments...!

Manoj Bajaj, August 08, 2002 - 3:26 am UTC

Tom, Life for programmer has never been easy. We started using the email utility..Now it sends attachments...many attachments tooo...but now one more secutiry reuirement..To encrypt the attachments and send ...imp. the user / receiver shoud be able to decrypt it ..how ?? hope u can show some path...

Tom Kyte
August 08, 2002 - 9:17 am UTC

beyond the scope of asktom here. It'll be very specific to the email client.

sorry.

Sending multiple emails

A reader, August 27, 2002 - 11:53 am UTC

Excellent work Tom,
Here is my problem..
I am trying to run the procedure given by you in a cursor...
(we need to automate the email sending procedure...a job will run in the morning)...
Recipient, to, cc, bcc...all the info will come from a table:
SQLWKS> desc tab_email
Column Name Null? Type
------------------------------ -------- ----
RECIPIENT VARCHAR2(500)
CC VARCHAR2(500)
BCC VARCHAR2(500)
SUBJECT VARCHAR2(500)
MESSAGE VARCHAR2(900)

recipient, cc, bcc will be comm-delimited list of email addresses for example,
a record from the tab_email (Recipient) will be stored exactly like this in the database:
'this@hotmail.com','that@yahoo.com'



CREATE OR REPLACE procedure send_emails as

cursor c_cur is
select * from tab_email;

begin

for c_rec in c_cur loop


mail_pkg.send
( p_sender_email => '"automated mail"',
p_from => '"automated mail"',
p_to => mail_pkg.array(c_rec.RECIPIENT),
p_cc => mail_pkg.array(c_rec.cc),
p_bcc => mail_pkg.array(c_rec.bcc),
p_subject => c_rec.subject,
p_body => c_rec.message);


end loop;

end;


this compiles fine.....but when I run it....
I get

ERROR at line 1:
ORA-20002: 501 5.5.4 Invalid arguments
ORA-06512: at "SYS.UTL_SMTP", line 86
ORA-06512: at "SYS.UTL_SMTP", line 204
ORA-06512: at "MANAGER.MAIL_PKG", line 54
ORA-06512: at line 1

If I don't pass values through a cursor....the procedure works O.K.
Is there a Tom Classic way of getting this going....

I am using PL/SQL solution because we don't have attachment issues.
We are using Oracle 8i (8.1.7.1.1)

Thanks..Always


Tom Kyte
August 27, 2002 - 1:39 pm UTC

Well, my line 54:

49 begin
50 g_mail_conn := utl_smtp.open_connection(g_mailhost, 25);
51
52 utl_smtp.helo(g_mail_conn, g_mailhost);
53 utl_smtp.mail(g_mail_conn, p_sender_email);
54

Here is where it differs, instead of calling UTL_SMTP.RCPT once ? it uses are
address_email function to call it potentially many times, building the ?To:? and
?Cc:? list for us as well. It builds the BCC list but we won?t actually send
that (we don?t want the recipients to see that list!)

55 l_to_list := address_email( 'To: ', p_to );
56 l_cc_list := address_email( 'Cc: ', p_cc );
57 l_bcc_list := address_email( 'Bcc: ', p_bcc );

contains no code, so I don't know if it is a problem with your:

sender_email
p_to
p_cc
p_bcc


Suggest you code this:

CREATE OR REPLACE procedure send_emails as

cursor c_cur is
select * from tab_email;

begin

for c_rec in c_cur loop

begin
mail_pkg.send
( p_sender_email => '"automated mail"',
p_from => '"automated mail"',
p_to => mail_pkg.array(c_rec.RECIPIENT),
p_cc => mail_pkg.array(c_rec.cc),
p_bcc => mail_pkg.array(c_rec.bcc),
p_subject => c_rec.subject,
p_body => c_rec.message);
exception
when others then
raise_application_error( -20002,
'"' || c_rec.recipient || '" "' || c_rec.cc || '" "' || c_rec.bcc || '"' );
end;

end loop;

end;


run that and your error message will including the "bad" stuff that you can test with from the command line to see what you need to fix up.

Another issue...thanks for the first reply

A reader, August 27, 2002 - 4:25 pm UTC

Tom,


I actually came up with another solution...again from your site...
I created a function:
CREATE OR REPLACE FUNCTION MAIL_ARRAY (PSTRING VARCHAR2) RETURN MAIL_PKG.ARRAY AS

L_ARRAY MAIL_PKG.ARRAY := MAIL_PKG.ARRAY();
BEGIN
FOR X IN (SELECT A.COLUMN_VALUE
FROM THE (SELECT CAST(in_list(PSTRING) AS MYTABLETYPE_VARCHAR2)
FROM DUAL) A
)
LOOP
L_ARRAY .EXTEND;
L_ARRAY (L_ARRAY.COUNT) := X.COLUMN_VALUE;
END LOOP;

RETURN L_ARRAY;

END MAIL_ARRAY;

/


Then I ran the procedure like this:
CREATE OR REPLACE PROCEDURE SEND_EMAILS AS

CURSOR C_CUR IS
select * from tab_email;

BEGIN

FOR C_REC IN C_CUR LOOP

MAIL_PKG.SEND
( P_SENDER_EMAIL => '"Automated Mail Message"',
P_FROM => '"Automated Mail Message"',
P_TO => MAIL_ARRAY(C_REC.RECIPIENT),
P_CC => MAIL_ARRAY(C_REC.CC),
P_BCC => MAIL_ARRAY(C_REC.BCC),
P_SUBJECT => C_REC.SUBJECT,
P_BODY => C_REC.MESSAGE);


END LOOP;

END;


This work's perfect...and there is always a "BUT" :)
My table structure that will feed the records to the cursor
will be like this:

SQLWKS> desc email
Column Name Null? Type
------------------------------ -------- ----
EMAILID NOT NULL NUMBER
RECIPIENT NOT NULL VARCHAR2(500)
CC VARCHAR2(500)
BCC VARCHAR2(500)
SUBJECT NOT NULL VARCHAR2(255)
SUBMITDT NOT NULL DATE
SENTYN NOT NULL VARCHAR2(1)
SENTDT DATE

SQLWKS> desc email_message
Column Name Null? Type
------------------------------ -------- ----
MESSAGEID NOT NULL NUMBER
EMAILID NOT NULL NUMBER
MESSAGE NOT NULL VARCHAR2(900)


so,
"CURSOR C_CUR IS
select * from tab_email;"

will change to
"
CURSOR C_CUR IS
SELECT E.EMAILID, M.MESSAGEID, E.RECIPIENT, CC,BCC, SUBJECT, SENTYN, SENTDT
FROM EMAIL E, EMAIL_MESSAGE M
WHERE E.EMAILID = M.EMAILID (+)
ORDER BY EMAILID, MESSAGEID;
"


email_message.emailid is an FK to EMAIL.emailid.
so that, an emailid can have multiple messages..so there won't be any constraint on the length of the message...keep concatenating...
fine...
"BUT"
Now we have declared p_body in mail_pkg.send as LONG...so that
is 32000 approx.
Maximum length of a message (all the messageid's combined for an emailid) that I have seen in our data is 16452.
(Concatenated message for an emailid will be passing as mail_pkg.send(p_body) parameter)

So, at some point there is a chance this code might break..
Is there a better way to do this...

Thanks Always...







Tom Kyte
August 27, 2002 - 4:39 pm UTC

rewrite my stuff to use CLOBS instead of LONGS and store the message in a clob instead.

If a plain text email exceeds 32k -- man, that must be one heck of an email.

CLOBS hmmmm

A reader, August 27, 2002 - 5:05 pm UTC

Tom,

:)))))))))))))))))
Well, it did go to 16452.....
We are sending contractors emails about their projects..something something...
it's not somebody writing their lifestory :))))))
Anyway,
I will change LONG to CLOB....

Thanks a zillion to the power infinity for the Superfly Quick replies...

You are the Best...



CLOB fails on utl_smtp.write_data :(

A reader, August 27, 2002 - 5:35 pm UTC

I changed procedure send to:

procedure send( p_sender_email in varchar2,
p_from in varchar2 default NULL,
p_to in array default array(),
p_cc in array default array(),
p_bcc in array default array(),
p_subject in varchar2 default NULL,
p_body in clob default NULL )

so, p_body is a CLOB now..
"BUT" it fails to compile..because data is varchar2

utl_smtp:
PROCEDURE write_data(c IN OUT NOCOPY connection,
data IN VARCHAR2);

Now, How was it working with LONG anyway?

Here is the line and the error:

70> utl_smtp.write_data(g_mail_conn, p_body );

"70/5 PLS-00306: wrong number or types of arguments in call to 'WRITE_DATA' "

Any ideas....

Thanks...



Tom Kyte
August 27, 2002 - 9:22 pm UTC

Well you have to rewrite the code ALL OF THE WAY down to the utl_smtp.write_data call and write the CLOB out 32k at a time!

getting error

A reader, August 28, 2002 - 9:35 pm UTC

getting

ORA-29532: Java call terminated by uncaught Java exception: java.lang.NullPointerException: Null buffer

on 8.1.7.1.1

worked ok on 8.1.7.3.0

any ideas...


Tom Kyte
August 29, 2002 - 5:21 pm UTC

Nope, you must have missed a grant or something like that.

Put some debug in there and snoop around - i've used this on pretty much every release of Oracle since 815

followup to my response above

A reader, August 28, 2002 - 9:40 pm UTC

Just wanted to clarify...
I am using utl_smtp...just the way you said to send email..
no java..then
Why this Java error..

Tom Kyte
August 29, 2002 - 5:22 pm UTC

UTL_SMTP is written in java.

Time for some debug. Find out where it is happening.

found the error

A reader, August 30, 2002 - 8:25 am UTC

if you pass null to the p_body..that's when ora-29532 java error occurs..
NVL took care of that issue..

Thanks Tom.....

excellent piece of art!

Arielito Lopez, September 10, 2002 - 12:10 pm UTC

thanks for this information...it helps a lot!

I get an error when I using Javamail

Mukesh Thakkar, September 24, 2002 - 2:09 pm UTC

Hi
I am running Oracle 8.1.7 RDBMS on windows NT/2000. I can get utl_smtp to work fine sending emails. However when I use the Javamail API as shown I get the following errors
javax.mail.SendFailedException: No recipient addresses
at javax.mail.Transport.send0(Transport.java:110)
at javax.mail.Transport.send(Transport.java:80)
at mail.send(mail:132)
Failed to send message...

Any ideas?
Thanks
Mukesh Thakkar

Tom Kyte
September 24, 2002 - 3:47 pm UTC

Well, thats a java exception -- you must have not sent the right inputs (like a recipient - a to list) down to the routine.

It worked fantastic on Oracle 9i on Sun Solaris !!! Thanks a lot

Arun Srivastav, October 10, 2002 - 9:52 am UTC

I followed all the steps, except deviated while running loadjava with user as system and I got errors, then went back to SYS and it ran through.

It is very very useful, specially in the project I am working with i.e. Digital Asset Management. A lot of files and reports are required to be mailed as attachment for reviews, reports, etc.

Thanks a lot !!!

load java Problem

Vikas Sharma, October 28, 2002 - 7:40 am UTC

hi Tom/Mark Piermarini,

I got the error while doing loadjava and creating javasource. But when i create the javasource in sys user i dont receive any errors and it gets created sucessfully. Following are the errors

loadjava -u sys/change_on_install@demo_mtl -o -r -v -f -noverify -synonym -g public mail8i.zip

resolving: mail8i/com/sun/mail/imap/protocol/FLAGS
Error while resolving class mail8i/com/sun/mail/imap/protocol/FLAGS
ORA-04043: object mail8i/com/sun/mail/imap/protocol/FLAGS does not exist

resolving: mail8i/com/sun/mail/imap/MessageLiteral
Error while resolving class mail8i/com/sun/mail/imap/MessageLiteral
ORA-04043: object mail8i/com/sun/mail/imap/MessageLiteral does not exist

resolving: mail8i/javax/mail/internet/SharedInputStream
Error while resolving class mail8i/javax/mail/internet/SharedInputStream
ORA-04043: object mail8i/javax/mail/internet/SharedInputStream does not exist
......
like That 392 Errors
*******************************************************

Following are the error when loading activation.zip
loadjava -u sys/change_on_install@demo_mtl -o -r -v -f -noverify -synonym -g public activation8i.zip

Error while granting to activation8i/javax/activation/SecuritySupport12$2
ORA-04042: procedure, function, package, or package body does not exist

Error while granting to activation8i/javax/activation/CommandMap
ORA-04042: procedure, function, package, or package body does not exist

Error while granting to activation8i/com/sun/activation/registries/MailcapTokenizer
ORA-04042: procedure, function, package, or package body does not exist

Error while granting to activation8i/javax/activation/MimeType
ORA-04042: procedure, function, package, or package body does not exist

Error while granting to activation8i/javax/activation/DataHandler
ORA-04042: procedure, function, package, or package body does not exist

Error while granting to activation8i/javax/activation/SecuritySupport12$4
ORA-04042: procedure, function, package, or package body does not exist
......
loadjava: 76 errors
*******************************

When i tried to create java source in it gives Errors,
But when i create the javasource in sys user i dont receive any errors and it gets created sucessfully.

ERROR for JAVA SOURCE mail when some other user:

LINE/COL ERROR
-------- -----------------------------------------------------
0/0 mail:98: Interface DataSource of nested class mail.
BLOBDataSource not found.

0/0 mail:132: Interface DataSource of nested class mail.
CLOBDataSource not found.

0/0 mail:54: Class Message not found.
0/0 mail:54: Class MimeMessage not found.
0/0 mail:59: Variable msg may not have been initialized.
0/0 mail:61: Variable msg may not have been initialized.
0/0 mail:62: Variable msg may not have been initialized.

LINE/COL ERROR
-------- -----------------------------------------------------
0/0 mail:65: Class MimeBodyPart not found.
0/0 mail:65: Class MimeBodyPart not found.
0/0 mail:68: Class MimeBodyPart not found.
0/0 mail:68: Class MimeBodyPart not found.
0/0 mail:77: Class MimeMultipart not found.
0/0 mail:77: Class MimeMultipart not found.
0/0 mail:86: Undefined variable or class name: Transport
0/0 Info: 14 errors

I created function send in sys and tried to send mail but that there alos i am to send mail and get
sys@DEMO.MIS1>/
Failed to send message...

The non java version is working fine. i could send mail with that.

My database version 8.1.7.0
I loaded activiation.zip first
errors i showed you while loading zip files.

Kindly help me.

Regards,

Vikas sharma

email

mo, October 30, 2002 - 9:06 am UTC

Tom:

If I want to CC several people do I create a variable that holds all emails included in ' ' and separated by a comma and use it in

v_email1:= 'mike@yahoo.com';
v_email2:= 'John@aol.com';
v_email3:= 'mary@msn.com';
v_cc_list := v_email1||','||v_email2||','||v_email3;

p_cc => mail_pkg.array( v_cc_list ),

2. Would the email package work if the p_to has a null variable while the p_cc has a list of emails or you have to have to. The reason I ask this is that sometimes you send emails based on user profile flag. The to person may have it off while the one on CC is on.

Thank you


Tom Kyte
October 31, 2002 - 4:33 pm UTC

not as I have the code written. you would do it just like the example does for the p_to parameter below:

tkyte@TKYTE816> begin
2 mail_pkg.send
3 ( p_sender_email => 'asktom_us@oracle.com',
4 p_from => 'Oracle Database Account <asktom_us@oracle.com>',
5 p_to => mail_pkg.array( 'asktom_us@oracle.com',
'thomas.kyte@oracle.com' ),
6 p_cc => mail_pkg.array( 'tkyte@oracle.com' ),
7 p_bcc => mail_pkg.array( 'utility@aria.us.oracle.com' ),
8 p_subject => 'This is a subject',
9 p_body => 'Hello Tom, this is the mail you need' );
10 end;
11 /

an array, not a comma delimited string. YOu would have to parse the string into an array somewhere.

email

mo, October 31, 2002 - 5:50 pm UTC

Tom:

1. What do you use to parse a string into an array. Do you have any reference for examples?

2. How about if I declared a variables of an array type

type emailArray is table of varchar2(8);
email emailArray:=emailArray(null,null,null,null,null;

Then I select first email into email(1) and second into
email(2) and so on.

Would just use this then:

p_to => mail_pkg.array(email)

would this work.


Tom Kyte
October 31, 2002 - 9:27 pm UTC

1) search for

str2table

for an example (on this site)

2) or just

...
l_emails mail_pkg.array := mail_pkg.array(); /* gotta use the SAME type, don't
invent your own!!!! */
....
begin
....
l_emails.extend(4);
l_emails(1) := ...
l_emaisl(2) := ....
......



and then just


p_to => L_emails,



..and under Oracle9i ?

Mario, December 02, 2002 - 10:35 am UTC

From your reply:

" loadjava -u sys/manager -o -r -v -f -noverify -synonym -g public mail8i.zip
loadjava -u sys/manager -o -r -v -f -noverify -synonym -g public "

1) But under Oracle9i you can log in as "sys" only with the special "as sysdba". How can I workaround it?

Apparently the "Java Developer’s Guide", for Oracle9iR2 obviously, doesn't say anything about this issue.

2) Is there a better way under Oracle9i to send an email with an attachment?

Thank you very much Tom

Mario from Rome, Italy

email

mo, December 04, 2002 - 8:23 am UTC

Tom:

Can you still use utl_smtp to send emails out out of the database to users outside of a firewall, if you have a database server that is not on the internet. Server has classified info and is only accessed through app server.

Thanks,



Tom Kyte
December 04, 2002 - 8:29 am UTC

only if you can send an email out from the command line using "mail" from the server.

Do you have an SMTP relay to the outside? if not, no go. Nothing to do with utl_smtp here, more with the firewall policies and how it is setup. If the database server HOST can send emails to the outside, then utl_smtp certainly can. If not, then no.

excellent

Mohammed Saleemuddin, December 31, 2002 - 12:15 pm UTC

Hi Tom,

Your procedure of sending mails from D2K was execellent.i got it within notime and is working fine till now.
here my reqiurements,realted to ur application.sending is ok.my question is ,when i recieve the mail,it will go to my exchange server.
what i want is,recieve the mails in D2k form itself.is there any possibility that i can store the incoming mails in D2K form instead of going in exchange server.plz,help me out in this matter.
waitng for ur answer.
thanks
Mohd.salim.
Riyadh.

Tom Kyte
December 31, 2002 - 1:01 pm UTC

forms is just an application development tool. It doesn't "store anything"

You must mean the database, the java apis above are capable of "reading" mail as well as sending it. You just need read up on the java mail api and then you'll have to build a set of tables and such to store the retrieved mail in.

loadjava error - please help

Michael, January 08, 2003 - 2:57 am UTC

Hi Tom

I have downloaded JavaMail 1.3 and did everything up to the point of loading mail8i.zip into the database.

When our DBA execute loadjava for mail8i.zip using the SYS account, she encountered 422 errors, a sample of these is:

resolving: temp/javamail13/extracted_mail/com/sun/mail/iap/Argument
Error while resolving class temp/javamail13/extracted_mail/com/sun/mail/iap/Argument
ORA-04043: object /8db2db4c_Argument does not exist

resolving: temp/javamail13/extracted_mail/com/sun/mail/iap/Protocol
Error while resolving class temp/javamail13/extracted_mail/com/sun/mail/iap/Protocol
ORA-04043: object /26640416_Protocol does not exist

resolving: temp/javamail13/extracted_mail/com/sun/mail/imap/protocol/FetchResponse
Error while resolving class temp/javamail13/extracted_mail/com/sun/mail/imap/protocol/FetchResponse
ORA-04043: object /3e15cf74_FetchResponse does not exist

We are using oracle 8i:

Connected to:
Oracle8i Enterprise Edition Release 8.1.7.0.0 - Production
With the Partitioning option
JServer Release 8.1.7.0.0 - Production

Could you please tell me where we went wrong?

Thanks in advance

Tom Kyte
January 08, 2003 - 4:33 pm UTC

try loading it not into sys, but your own schema and see what happens. that way you can work with it.

(not sure, but maybe i have the loadjava's backwards? try activation first)

Benchmarking

Scott, January 23, 2003 - 12:47 am UTC

G'day Tom

For those who are interested, I did some benchmarking (on our development box) to compare the two emailing methods.

1 - SMTP
2 - Javamail

The SMTP benchmark used on session, and mailed within that session. This was much better performance than using one session per email.

Each count represents a batch of 5 emails, to split the load, in case the server activity varied.
Sum and avg is in hsecs.

No attachments...(ie - 200 emails - 100 each)

SUM_1 SUM_2 AVG_1 AVG_2 COUNT_1 COUNT_2
--------- ---------- ---------- ---------- ---------- ----------
3423 2040 85.58 51 20 20

44kb attachment included.

SUM_1 SUM_2 AVG_1 AVG_2 COUNT_1 COUNT_2
--------- ---------- ---------- ---------- ---------- ----------
202041 74569 3741.5 1380.91 27 27

So when using attachments, Javamail had even better performance compared to UTL_SMTP.

Here are some other runs with various conditions varied. Each number represents a run of 100/50 emails, so server usage may have affected some of these results.
Javamail outperformed UTL_SMTP in all but runs 7 and 8.
The first two runs using UTL_SMTP (1 and 3) are opening one session per email - hence the long run-time.
-- (100 emails each)
1 #1: 10752 hsecs (10.75 seconds)
2 #2: 6100 hsecs
3 #1: 10329 hsecs
4 #2: 5247 hsecs
5 #1: 6537 hsecs
6 #2: 5287 hsecs
7 #1: 4789 hsecs
8 #2: 5047 hsecs
9 #1: 6060 hsecs
10 #2: 2910 hsecs
11 #1: 7344 hsecs
12 #2: 4214 hsecs
-- attachments (50 emails each)
13 #1: 46616 hsecs
14 #2: 19054 hsecs
15 #1: 40845 hsecs
16 #2: 17496 hsecs

Thanks for your contributions, Tom.


Great - Spot on

Michael, January 24, 2003 - 3:18 am UTC

Following your suggestion, we have successfully loadjava for the zip files and implemented it.

You were right in saying activation8i.zip needs to be loaded first.

Thanks again.

util_smtp package

naivedya, February 20, 2003 - 2:34 am UTC

It is very good, for sending mails. But at the same time I wish to attach my attachments (txt, doc, etc. or database fields). How do I do this with PL/SQL (no Java) ??

Rgds


Tom Kyte
February 20, 2003 - 7:29 am UTC

with tons and tons of code.

Lets see, you would have to write a mime encoder.
You would have to write a base64 encoder.
You would have to write tons and tons and tons of code.

Now, in 8i, utl_smtp is in java so you are already using java -- in for a penny -- in for a pound as they say. you are using java already so just add a "little bit more" and you won't have to write scads of code.

Characters not in us7ascii

Salaam Yitbarek, March 26, 2003 - 3:36 pm UTC

So we are now successfully sending email using UTL_SMTP all except for one thing -- accented characters in the subject field.

From the Solaris command line, I can successfully send mail with accented characters. However, using UTL_SMTP, this does not work.

I don't mind it not working in the body, since we're sending html (&agrave instead of à), but the subject line is a problem.

Our database character set is we8iso8859pi.

Tom Kyte
March 26, 2003 - 6:35 pm UTC

see
</code> http://docs.oracle.com/docs/cd/A87860_01/doc/appdev.817/a76936/utl_smtp.htm#1000695 <code>

...
Note that the original SMTP protocol communicates using 7-bit ASCII. Using UTL_SMTP, all text data (in other words, those in VARCHAR2) will be converted to US7ASCII before it is sent over the wire to the server.
......


You can use javamail instead if you like.

UTL_SMTP and sending mail

A K Prasanna, March 28, 2003 - 12:43 am UTC

I was pretty frustrated that "Expert One on One Oracle"
is not available in the library to refer to this topic but I don't think I need any book now.Thank you very much.

email table

mo, April 24, 2003 - 2:54 pm UTC

Tom:

1. How do you send results of the emp table (or any sql query) using the above email package.

Basically the result of this SQL command
select * from emp1;

Thank you,


Tom Kyte
April 24, 2003 - 3:34 pm UTC

same way you get it onto an html page.

run it, fetch it, send it. put it in a big string, email it.

email table

mo, April 24, 2003 - 3:54 pm UTC

Tom:

I did this:

v_data long default null;

FOR x in (select * from emp)
LOOP
v_data:=v_data||x.empno||' '||x.ename||' '||x.job||' '
||x.mgr||chr(10);
END LOOP;

then in the email package
p_body => v_data

However the data is not lined up as it does in SQL*PLUS.

Is this how you do it and can i get it lined up?

Thank you,


Tom Kyte
April 24, 2003 - 4:22 pm UTC

well, I don't email myself "select * from table" output.

I email things like "hey, click on this link and you'll get a really pretty report on the web".

But anyway, think fixed width

to_char( x.emp, '99999' || ' ' || rpad( x.ename, 20 ) || ' ' || rpad( ....

email

mo, April 24, 2003 - 6:05 pm UTC

Tom:

1. When you schedule the job as
dbms_job.submit(l_job,'SEND_EMAIL(JOB);');
DOes that send the email as soon as you hit commit?

I did it but it did not send an email. Is it because
job_queue_processes = 0.

2. Do you delete records in tables email_parameters and job table after you commit or every period.

Thank you

Tom Kyte
April 24, 2003 - 6:24 pm UTC

1) if you do not have job queues set up to run jobs, it'll not run. set up the job_queue_processes and it'll send shortly after you commit.


2) you can do whatever suits your needs, what I do isn't relevant here. I keep them as an audit and purge every now and again when I feel like it with truncate.

Large to Lists

Randall, April 25, 2003 - 3:09 pm UTC

Tom, Thanks for all the help. We have utl_smtp in 8.1.7 working great now for some time. We use it to notify employees when changes are scheduled on systems that would affect them.

We did get an error today,
"ORA-20001: 452 Too many recipients"

The email that it was tring to send had 512 names on it with the TO list having a length of 14215. The email body is only about 6k and will never have a body bigger that 10k. Even thought this large TO list is not normal, it can happen. So I guess I will write some logic to break up the TO list and send multi SMTP emails.

Can you tell me what the limits are for UTL_SMTP for:
1. number of recipients
2. total size of TO: list (can you have multi TO: headers?)
3. max size of subject line
4. Does the 32k limit include body, TO list, and subject or just the size of the body.

Thanks for all the help and have a good weekend.



Tom Kyte
April 25, 2003 - 3:52 pm UTC

this is NOT a utl_smtp limit.

this IS a smtp limit imposed by your SMTP server


snipped from RFC 2821 which talks about this



4.5.3.1 Size limits and minimums
[snip]
recipients buffer
The minimum total number of recipients that must be buffered is
100 recipients. Rejection of messages (for excessive recipients)
with fewer than 100 RCPT commands is a violation of this
specification. The general principle that relaying SMTP servers
MUST NOT, and delivery SMTP servers SHOULD NOT, perform validation
tests on message headers suggests that rejecting a message based
on the total number of recipients shown in header fields is to be
discouraged. A server which imposes a limit on the number of
recipients MUST behave in an orderly fashion, such as to reject
additional addresses over its limit rather than silently
discarding addresses previously accepted. A client that needs to
deliver a message containing over 100 RCPT commands SHOULD be
prepared to transmit in 100-recipient "chunks" if the server
declines to accept more than 100 recipients in a single message.

Errors due to exceeding these limits may be reported by using the
reply codes. Some examples of reply codes are:

500 Line too long.
or
501 Path too long
or
452 Too many recipients (see below)
or
552 Too much mail data.

RFC 821 [30] incorrectly listed the error where an SMTP server
exhausts its implementation limit on the number of RCPT commands
("too many recipients") as having reply code 552. The correct reply
code for this condition is 452. Clients SHOULD treat a 552 code in
this case as a temporary, rather than permanent, failure so the logic
below works.

When a conforming SMTP server encounters this condition, it has at
least 100 successful RCPT commands in its recipients buffer. If the
server is able to accept the message, then at least these 100
addresses will be removed from the SMTP client's queue. When the
client attempts retransmission of those addresses which received 452
responses, at least 100 of these will be able to fit in the SMTP
server's recipients buffer. Each retransmission attempt which is
able to deliver anything will be able to dispose of at least 100 of
these recipients.

If an SMTP server has an implementation limit on the number of RCPT
commands and this limit is exhausted, it MUST use a response code of
452 (but the client SHOULD also be prepared for a 552, as noted
above). If the server has a configured site-policy limitation on the
number of RCPT commands, it MAY instead use a 5XX response code.
This would be most appropriate if the policy limitation was intended
to apply if the total recipient count for a particular message body
were enforced even if that message body was sent in multiple mail
transactions.

email

mo, April 25, 2003 - 3:50 pm UTC

Tom:

1. The email package seems to mandate a p_from email address. What about if the email message is an a system alert and it is not really from anyone. What do you do in this case? Do you put a dummy email address?

2. IF you have multiple send email triggers do you always use the same email_parameters table. Would there ever be a conflict in job id if one for example schedules the job two days later?

Thank you,



Tom Kyte
April 25, 2003 - 3:55 pm UTC

1) put in postmaster@host or something meaningful. mail cannot be sent without a from

2) one table, dbms_job generates a unique id using a sequence.

email with two emails addresses

mo, May 07, 2003 - 1:02 pm UTC

Tom:

1. Do you know why the email package fails when I add two variables in the p_to list?

2. It seems also if I put a variable for the cc_list it does not work if that vairable is null. I had to create an if statement to check if v_cc_email is null and include if it is not and not include if it is. Does this sound correct?

mail_pkg.send(
p_sender_email=>l_rec.sender_email,
p_from=>null,
p_to=>mail_pkg.array(l_rec.pvt_email,l_req.request_email),
p_cc=>mail_pkg.array(),
p_bcc=>mail_pkg.array('xxx@yahoo.com'),
p_subject => 'Request# '||l_rec.request_id||' - Shipment has been Completed',
p_body => l_rec.email_data);

ERROR at line 1:
ORA-20002: 501 5.5.2 Syntax error in parameters scanning "TO"
ORA-06512: at "SYS.UTL_SMTP", line 86
ORA-06512: at "SYS.UTL_SMTP", line 223
ORA-06512: at "PSSADMIN.MAIL_PKG", line 13
ORA-06512: at "PSSADMIN.MAIL_PKG", line 55
ORA-06512: at line 7


Tom Kyte
May 08, 2003 - 9:01 am UTC

probably has nothing to do with "two"

probably has everything to do with your email address not being well formed in one of those two variables...

without an isolated, standalone, complete, runnable by my test case -- well, i won't be able to say.



email

mo, May 08, 2003 - 10:47 am UTC

Tom:

1. The variables are defined for two valid email addresses. You can set any two variables and try to pass them into the p_to list and it will fail. I created an array variable instead. The problem with array vairable "l_emails" is that you have to extend it exactly to the number of emails you are sending. When I did l_emails.extend(2) and my second email in the email_parameters table was null the email package failed. I had to pass i and figure out what i is.

Tom Kyte
May 08, 2003 - 6:15 pm UTC

show us the test case -- eh?


thats all I ask, self contained, reproducible, SMALL <<<=== really important.

your solution described fits NOT AT ALL with the problem presented:

mail_pkg.send(
p_sender_email=>l_rec.sender_email,
p_from=>null,
p_to=>mail_pkg.array(l_rec.pvt_email,l_req.request_email),
p_cc=>mail_pkg.array(),
p_bcc=>mail_pkg.array('xxx@yahoo.com'),
p_subject => 'Request# '||l_rec.request_id||' - Shipment has been Completed',
p_body => l_rec.email_data);



there is nothing to .extend there -- you are creating a temporary array. what you describe as your fix could have nothing to do with the example provided.

Send email does not work constantly

A Reader, May 09, 2003 - 3:29 pm UTC

Hi Tom,
I have system trigger that uses the send mail procedure to send email to me whenever there is a defined server error. The trigger sometimes works fine, I mean I receive emails when the errors occur. Sometimes it does not work (I don’t receive any emails where the errors occur). I know that by checking the trace files because there will be a trace file generated when the defined error appears. I want receive all of the emails when errors occur. My question: Where should I start with the debugging, the procedure or the trigger? Or the ora_is_servererror sometime does not response to the errors? My tests worked fine. The sendmail procedure was copied and modified from the beginning of this thread.
Thank you for your help.

CREATE OR REPLACE TRIGGER systrig_servererror
after servererror on database
begin
IF (ora_is_servererror(60) or ora_is_servererror(4020)) THEN
sendmail('dba@ourcompany.com','dba@ourcompany.com','A deadlock is detected in prod_db');
ELSIF (ora_is_servererror(1555)) THEN
sendmail('dba@ourcompany.com','dba@ourcompany.com','Check rollback segments in prod_db');
END IF;
end;
/



Tom Kyte
May 09, 2003 - 5:10 pm UTC

If the sending of emails did not work -- asktom would be broken, my internal website would be broken.

suggest you stick an "insert into msg_table (some string)" to see that the error is getting fired.

1555's are not written to traces.

email

mo, May 09, 2003 - 7:03 pm UTC

TOm:

Here is the code. The email fails if the second email is null.

PSD> edit
Wrote file afiedt.buf

1 declare
2 l_rec email_parameters%rowtype;
3 l_emails mail_pkg.array:=mail_pkg.array();
4 begin
5 select * into l_rec from email_parameters where id=108;
6 dbms_output.put_line(l_rec.sender_email);
7 dbms_output.put_line(l_rec.pvt_email);
8 dbms_output.put_line(l_rec.request_email);
9 l_emails.extend(2);
10 l_emails(1) := l_rec.pvt_email;
11 l_emails(2) := l_rec.request_email;
12 mail_pkg.send(
13 p_sender_email=>l_rec.sender_email,
14 p_from=>null,
15 p_to=>l_emails,
16 p_cc=>mail_pkg.array(),
17 p_bcc=>mail_pkg.array(),
18 p_subject => 'Request# '||l_rec.request_id||' - Shipment has been Completed',
19 p_body => l_rec.email_data);
20* end;
21 /

declare
*
ERROR at line 1:
ORA-20002: 501 5.5.2 Syntax error in parameters scanning "TO"
ORA-06512: at "SYS.UTL_SMTP", line 86
ORA-06512: at "SYS.UTL_SMTP", line 223
ORA-06512: at "IMSADMIN.MAIL_PKG", line 13
ORA-06512: at "IMSADMIN.MAIL_PKG", line 55
ORA-06512: at line 12



Tom Kyte
May 09, 2003 - 7:31 pm UTC

It is exactly what I said above then


probably has everything to do with your email address not being well formed in
one of those two variables...


tell me, is 'null' a valid email? no, it is not. Hence, you get the SMTP error (not an oracle error) of 501 saying "hey, that is not a valid well formed email address"



email

mo, May 09, 2003 - 10:41 pm UTC

Tom:

1. How would you get around it if one of the cc emails is null. Do you always check how many emails are not null and then do extend(i) rather than a fixed count?

2. The email package works if one of the emails is not valid at all? e.g, if i type 123@yahoo.com it will still work, even though it is not valid email?

Tom Kyte
May 10, 2003 - 7:33 am UTC

i would make darn sure there were no null emails in the array

obviously, since you own the code, you can modify the lowest level routine to just ignore nulls.


123@yahoo.com is perfectly "valid". It might not exists, but it conforms to the rules for email address format.

mail_pkg not working in the trigger

asusarla, May 12, 2003 - 7:16 pm UTC

This goes into Exception and uses send_mail
li_rec changerequest%ROWTYPE;
CURSOR li (arg IN NUMBER) IS
SELECT * FROM changerequest WHERE changerequestid= arg;
BEGIN
SELECT emailaddress, preferredname, surname
INTO recipient, givenname, surname
FROM mituser
WHERE mituserid = :new.raisedby;
IF :new.statuslookup = 8 THEN
subjectline := 'Your New Follow-up request #'||:new.changerequestid;
message_body := 'Dear '||givenname||' '||surname||','||crlf||crlf;
message_body := message_body||'Thank you for submitting your ';
message_body := message_body||'Follow-up ';
message_body := message_body||'request # '||:new.changerequestref||'.'||crlf||crlf;
message_body := message_body||'Your request for the following ';
message_body := message_body||'has been received:'||crlf||crlf;
message_body := message_body||'changerequestid';
OPEN li (:new.changerequestid);
LOOP
FETCH li INTO li_rec;
EXIT WHEN li%NOTFOUND;
message_body :=message_body||SUBSTR(RPAD(li_rec.changerequestref,14),1,14)||tab;
message_body :=message_body||SUBSTR(RPAD(li_rec.shortdescription,16),1,16)||crlf;
END LOOP;
message_body := message_body||crlf||' Please do not reply to it.';
End If;
MAIL_PKG.SEND(
p_sender_email => 'aparna.susarla@barnardos.org.nz',
p_from => 'The Request Processing System
<aparna.susarla@barnardos.org.nz>',
p_to => mail_pkg.array('aparna.susarla@barnardos.org.nz',recipient),
p_cc => mail_pkg.array('aparna.susarla@barnardos.org.nz '),
p_bcc => mail_pkg.array('aparna.susarla@barnardos.org.nz'),
p_subject => subjectline,
p_body => message_body);
EXCEPTION
WHEN OTHERS THEN
BEGIN
SEND_MAIL(

Tom Kyte
May 12, 2003 - 7:20 pm UTC

when others means you have a bug in your code.

get rid of it. then you'll actually be able to tell what bug you have as you'll get a meaningful error message.

mail_pkg not working in the trigger

asusarla, May 12, 2003 - 9:58 pm UTC

The other part of this trigger is as follows. I get an email with send_mail procedure with the message.If I try to run it with just mail_pkg does not allow the table to be updated.

EXCEPTION
WHEN OTHERS THEN
BEGIN
SEND_MAIL(
P_SENDER => 'aparna.susarla@barnardos.org.nz',
P_RECIPIENT => recipient,
P_MESSAGE => 'A problem occurred during the firing of '||
'trigger trg_changerequeststatus '||
'for request #'||:new.changerequestid);
EXCEPTION
WHEN OTHERS THEN
null;
END;
END;
/

Tom Kyte
May 13, 2003 - 7:00 am UTC

you have a bug.

the "when others" exception handler is hiding this bug from you.

"when others" in code that is not followed by "RAISE" is a bug. You have two that I see. What happens when send mail fails? Oh - no one EVER knows.

lose the when others, fix the third bug that is hiding in there once you know where and what it is!

Bulk email and sessions

Bastiaan, May 13, 2003 - 8:56 am UTC

Hi Tom,

We are using a similar procedure to send mail from our (PL/SQL web-) applications. From one of these applications we send personalised mail to people on a mailing list. We have a job scheduled to handle this. Now we have reached a point where our mailing list contains about 1500 mail-adresses, and the procedure that is scheduled in the job starts to fail. After investigating it turned out that the procedure failed every time it reached the 493rd person on the list. At that time there were 7 other sessions active (checked in v$sessions). Turns out that 493 + 7 is the maximum number of sessions we specified in the init.ora. Does every utl_smtp connection to a mailserver cause a (hidden) session to be started? Or is this just a coincidence?


Tom Kyte
May 13, 2003 - 9:08 am UTC

believe it is a coincidence. I send hundreds/thousands of emails daily using this technique.


do you have an error message.

A reader, May 13, 2003 - 11:57 am UTC

hello tom,

I took this from your 1st sample above:

declare
l_mailhost VARCHAR2(255) := 'DEESSMAIL';
l_mail_conn utl_smtp.connection;

p_sender VARCHAR2(50) := 'me@somewhere.net';
p_recipient VARCHAR2(50) := 'me@somewhere.net';
p_message VARCHAR2(20) := 'message content';

BEGIN
l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
utl_smtp.helo(l_mail_conn, l_mailhost);
utl_smtp.mail(l_mail_conn, p_sender);
utl_smtp.rcpt(l_mail_conn, p_recipient);
utl_smtp.open_data(l_mail_conn );
utl_smtp.write_data(l_mail_conn, p_message);
utl_smtp.close_data(l_mail_conn );
utl_smtp.quit(l_mail_conn);
end;

but got only EMPTY messages. can you give some advice?

Tom Kyte
May 13, 2003 - 4:54 pm UTC

I just used that block (changed the email/l_mailhost) and recieved:

From - Tue May 13 16:53:30 2003
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
Return-Path: <tkyte@oracle.com>
Received: from rgmum12.us.oracle.com by rgmum13.us.oracle.com
with ESMTP id 188485611052859142; Tue, 13 May 2003 14:52:22 -0600
Return-Path: <tkyte@oracle.com>
Received: from rgmgw4.us.oracle.com by rgmum6.us.oracle.com
with ESMTP id 157896281052858993; Tue, 13 May 2003 16:49:53 -0400
Received: from rgmgw4.us.oracle.com (localhost [127.0.0.1])
by rgmgw4.us.oracle.com (Switch-2.1.5/Switch-2.1.0) with ESMTP id h4DKnoa16288
for <thomas.kyte@rgmumsmtp.oraclecorp.com>; Tue, 13 May 2003 14:49:51 -0600 (MDT)
Received: (from mailora@localhost)
by rgmgw4.us.oracle.com (Switch-2.1.5/Switch-2.1.0) id h4DKnmb16120
for thomas.kyte@rgmumsmtp.oraclecorp.com; Tue, 13 May 2003 14:49:48 -0600 (MDT)
X-Authentication-Warning: rgmgw4.us.oracle.com: mailora set sender to tkyte@oracle.com using -f
Received: from rgmgw4.us.oracle.com (localhost [127.0.0.1])
by rgmgw4.us.oracle.com (Switch-2.1.5/Switch-2.1.0) with ESMTP id h4DKnLa15341
for <tkyte@oracle.com>; Tue, 13 May 2003 14:49:21 -0600 (MDT)
Received: from gmamersmtp.oraclecorp.com (dhcp-amer-vpn-gw2-west-141-144-91-44.vpn.oracle.com [141.144.91.44])
by rgmgw4.us.oracle.com (Switch-2.1.5/Switch-2.1.0) with SMTP id h4DKnLJ15321
for tkyte@oracle.com; Tue, 13 May 2003 14:49:21 -0600 (MDT)
Date: Tue, 13 May 2003 14:49:21 -0600 (MDT)
From: tkyte@oracle.com
Message-Id: <200305132049.h4DKnLJ15321@rgmgw4.us.oracle.com>

message content



As my email -- sounds like it might be a problem with your email client, ask it to show you the RAW email message (like I did above -- ctl-u if you are using mozilla, although mozilla shows it right the first time)


we are just talking "straight to smtp" here. You can do this with telnet - so the issue is NOT in the database.



Bulk email and sessions part II

Bastiaan, May 14, 2003 - 4:02 am UTC

Hi Tom,

Thank you for looking into my problem. The error messages I get back from the procedure are:

ORA-29278: SMTP transient error: 421 Service not available
ORA-00018: maximum number of sessions exceeded

I don't understand this because there is only 1 job, that runs the procedure. The procedure just takes a cursor loop through a table, and sends an email for every record...

My idea is that it's maybe the mail-server that doesn't accept any more connections (because of the 421 SMTP error), but within the procedure the smtp connection is closed, and at any given moment there should be only one connection from the database to the mailserver...

Tom Kyte
May 14, 2003 - 7:29 am UTC

I haven't seen this myself -- but then, I use one connection call period in my procedures.



Seding Email !

vinodhps, July 07, 2003 - 1:18 am UTC

Hi.. Tom ,
Hope you are fine,

as you said i created the procedure.. but iam getting the same error , how to solve this problem can you please help me out..

oiisdba@TEST902> create or replace
2 PROCEDURE send_mail (p_sender IN VARCHAR2,
3 p_recipient IN VARCHAR2,
4 p_message IN VARCHAR2)
5 as
6 -- Note that you have to use a host
7 -- that supports SMTP and that you have access to.
8 -- You do not have access to this host and must change it
9 l_mailhost VARCHAR2(255) := 'tnpl.co.in';
10 l_mail_conn utl_smtp.connection;
11 BEGIN
12 l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
13 utl_smtp.helo(l_mail_conn, l_mailhost);
14 utl_smtp.mail(l_mail_conn, p_sender);
15 utl_smtp.rcpt(l_mail_conn, p_recipient);
16 utl_smtp.open_data(l_mail_conn );
17 utl_smtp.write_data(l_mail_conn, p_message);
18 utl_smtp.close_data(l_mail_conn );
19 utl_smtp.quit(l_mail_conn);
20 end;
21 /

Procedure created.

oiisdba@TEST902> set serveroutput on
oiisdba@TEST902> declare
2 l_start number := dbms_utility.get_time;
3 begin
4 send_mail( 'someone@there.com',
5 'shabobby@yahoo.com', 'hey there' );
6 dbms_output.put_line
7 ( round( (dbms_utility.get_time-l_start)/100, 2 ) ||
8 ' seconds' );
9 end;
10 /
declare
*
ERROR at line 1:
ORA-29278: SMTP transient error: 421 Service not available
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 138
ORA-06512: at "OIISDBA.SEND_MAIL", line 11
ORA-06512: at line 4


Tom Kyte
July 07, 2003 - 7:28 am UTC

that means, just as it did before, that your host you are using is not running smtp services. tnpl.co.in is not running smtp on port 25.

ask your SA's where there is an smtp server in your network that does relaying.

Sending Email !

vinodhps, July 07, 2003 - 8:24 am UTC

Hi.. Tom,
we got only one mail server and can we get the host name if i know the ip address of mail server, if yes can you tell me .
if i try with that ip address iam getting error

oiisdba@TEST902> /
declare
*
ERROR at line 1:
ORA-29279: SMTP permanent error: 553 sorry, that domain isn't in my list of allowed rcpthosts
(#5.7.1)
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 98
ORA-06512: at "SYS.UTL_SMTP", line 240
ORA-06512: at "OIISDBA.SEND_MAIL", line 14
ORA-06512: at line 4

It is SMTP mail server only ..
can you help me Tom

Tom Kyte
July 07, 2003 - 8:44 am UTC

you are going to need to talk to your system admins here, this is not an Oracle error, it is purely an SMTP configuration issue at this point.

it is probably that you are not allowed to relay mail to @there.com

Flemming, July 16, 2003 - 6:48 am UTC

Hi Tom
I have a problem with the time-stamp of the email. In my code I have this statement:
utl_smtp.write_data(v_smtp_connection, 'DATE: '|| to_char(sysdate,'DD-MON-YYYY HH24:MI') || utl_tcp.CRLF);
I have verified that the time is correct in the code, but on the email the label for Sent shows a time that is 2 hours later. Any ideas ?
/Flemming

Tom Kyte
July 16, 2003 - 9:35 am UTC

timezones perhaps -- if it is correct to the 'minute', i would guess a time zone change is taking place either along the way or by the email client itself.

Ackownledgement Email...

vinodhps, July 20, 2003 - 7:19 am UTC

Hi Toms,
Now its working fine, and your Book and your website are so useful and your new book was good.. i read all the 3 chapters.. waiting to get one copy for me .. so when it is going to come in market.. (India)..

well i got recuirement, that after we send mail, is it possible to know that whether they have opened the mail , something like Ackownledgement - mail.when the opened.....

Is it possible Tom , If so how can we do that tom.

Thankyou


Tom Kyte
July 20, 2003 - 9:15 am UTC

that is a protocol private to email -- the CLIENT recieving it must be willing to send it (i for example, have that disabled -- i do not send ack's back)

then, you would need a client to read it.

In short - yes, you could -- but it would be fairly involved and outside of "an example" (meaning I'm not going to build it)

You would need to

a) find out what the protocol for acknowledgement is (something in the header undoubtably)

b) send that

c) figure out how you want to read the email (could be a java stored procedure in the database if you wanted)

acknowledgemen Mail

vinodhps, July 21, 2003 - 1:52 pm UTC

Hi Toms ....
for you responce ..
i searched in google.. i could not able to find any document which will help me..out ..

i will try myself..can you give some useful links or site where i can find anything about acknowledgemen mail ...tom

all i want is just to know wether they read the mail or not.

a) "(something in the header undoubtably)"

Can you explain this tom.

Thank you for your time



Tom Kyte
July 21, 2003 - 3:34 pm UTC

to tell whether they read a mail, the CLIENT must participate (meaning there is NO WAY you can rely on this even a little -- I for example disallow 100% the use of this feature on my client, it is NONE of your business when or if I've read your mail).

there must be some header that does this, me, being a database guy, not an email guy -- doesn't know the header in general.

try searching for

"return receipt" "header"

on google

Returning mail

vinodhps, July 22, 2003 - 10:17 pm UTC

Hi Tom,
Thanks I will try to get that
Thanks for you time tom


sending email attachments

Able, July 23, 2003 - 5:53 am UTC

Hi Tom,

Please help me, as I got the following errors which is misguiding when i run the script to create procedure for sending attachment through mail. I have successfully loaded mail.jar and activation.jar files (Javamail API)

I appreciate your earlier reply.


Errors for JAVA SOURCE MAIL:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 MAIL:83: Interface DataSource of nested class mail.
BLOBDataSource not found.

0/0 MAIL:31: Class Message not found.
0/0 MAIL:32: Class MimeMessage not found.
0/0 MAIL:38: Variable msg may not have been initialized.
0/0 MAIL:41: Variable msg may not have been initialized.
0/0 MAIL:44: Variable msg may not have been initialized.
0/0 MAIL:45: Variable msg may not have been initialized.
0/0 MAIL:46: Variable msg may not have been initialized.
0/0 MAIL:49: Class MimeBodyPart not found.
0/0 MAIL:49: Class MimeBodyPart not found.
0/0 MAIL:52: Class MimeBodyPart not found.
0/0 MAIL:52: Class MimeBodyPart not found.
0/0 MAIL:62: Class MimeMultipart not found.
0/0 MAIL:62: Class MimeMultipart not found.
0/0 MAIL:71: Undefined variable or class name: Transport

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 Info: 15 errors

Sending e-mail to groups of users at once

Daryl Green, July 30, 2003 - 2:23 pm UTC

Tom,

How can you use these methods to send e-mails to a group of users (at once) instead of addressing them each individually. I have security set up on my NT 8.1.6.3 database with profiles and would like to automatically send an email to all users whose password will expire in 10 or less days on a daily basis until the password has been successfully changed. Also, i have a web form (using Webdb) to allow user to change their passwords. I want to send an individual e-mail to them. How can this be done!

Thanks for all of you help!!!

Tom Kyte
July 30, 2003 - 2:46 pm UTC

you have to make an RCPT call once for each user is all.

Very nice

Sikandar Hayat, July 31, 2003 - 6:45 am UTC

Hi TOM,
I tried this 8i but it was not working there may be due to my poor knowledge of Java. Now in Oracle9i Rel2 I have tried and it is working.

Thanks for such a cool stuff.

How to send email to local users?

Sikandar Hayat, August 08, 2003 - 3:33 am UTC

I am able to send email to those who have SMTP account. Now our many local users don't have internet account so let me know if is there any way to send emails to them. We are using window with exchange server 5.5.

Tom Kyte
August 10, 2003 - 11:31 am UTC

exchange supports SMTP.

I am not getting the Message body

Sara, September 03, 2003 - 3:12 pm UTC

I have used your query...but i am not getting any message body..? what is the problem in the query.

create or replace PROCEDURE send_mail (p_sender IN VARCHAR2,
p_recipient IN VARCHAR2,
p_message IN VARCHAR2)
as
l_mailhost VARCHAR2(255) := 'smtpgw.cdc.gov';
l_mail_conn utl_smtp.connection;
BEGIN
l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
utl_smtp.helo(l_mail_conn, l_mailhost);
utl_smtp.mail(l_mail_conn, p_sender);
utl_smtp.rcpt(l_mail_conn, p_recipient);
utl_smtp.open_data(l_mail_conn );
utl_smtp.write_data(l_mail_conn, p_message);
utl_smtp.close_data(l_mail_conn );
utl_smtp.quit(l_mail_conn);
end;

begin
send_mail( 'bcv5@cdc.gov',
'bcv5@cdc.gov',
'Hello Tom' );
end;
If i run the procedure all i am getting is the from email id.

Awaiting your response



Tom Kyte
September 04, 2003 - 8:36 am UTC

in your email client, use the option to view the original unformatted email. Perhaps your client is hiding it from you. (this works -- this is just standard smtp stuff -- nothing simplier -- but I can imagine the email client you are using it mucking it up somehow. Lets see the "real" email)

reply immd..

suresh, September 16, 2003 - 10:44 am UTC


How to pass PL/SQL TABLE FROM D2K TO PL/SQL PROCEDURE. ?

I declared one Package of two pl/sql table types and one Procedure , i am access these types(declare variable of that type) in D2K and papulate some values on that pl/sql tables(fornt end), after that i called Packed Procedure by passing these PL/SQL Tables from frontend D2K TO THAT Package Procedure backend , how to do this ?

is their any Prob's appares ? by passing frontend tables(pl/sql) to back end of (same type).
reply tom, immd...



Tom Kyte
September 16, 2003 - 12:47 pm UTC

sorry, don't do forms, don't have forms, haven't touched forms since 95'

you can try otn.oracle.com -> discussion forums.



Sending fax

A reader, September 23, 2003 - 8:59 am UTC

Tom

Is there anything 8i , 9i or 10G which would enable faxing from the database, just like emailing from the database, illustrated in this example ?

Thanks

Tom Kyte
September 23, 2003 - 11:04 am UTC

drop a java stored procedure in there -- there must be one out there that can interface with some fax software.

(oracle collaboration suite does this as well)

For time zones

Jon, September 25, 2003 - 11:15 am UTC

Thanks Tom, this works great for us.

We were concerned at first because our time was coming out wrong. Then we realized that we needed to append ' -0400' to the date so that it would show the time for the correct time zone (in our case, EST). Just thought other people may have ran into this problem...

Getting error when using JavaMail

Andrew T. Nguyen, October 02, 2003 - 10:43 pm UTC

Hi Tom,

I am running Oracle 8.1.7 on Windows 2000. I can get UTL_SMTP to send emails fine. However when I use the Javamail API as shown, I get the following errors:

javax.mail.SendFailedException: Sending failed;
nested exception is:
class
javax.mail.MessagingException: Could not connect to SMTP host: localhost, port:
25;
nested exception is:
java.net.ConnectException: Connection refused
at javax.mail.Transport.send0(Transport.java:218)
at javax.mail.Transport.send(Transport.java:80)
at mail.send(mail:86)
Failed to send message...

I used the same smtp host in the Utl_smtp and it worked fine. Any idea?
Thanks

Tom Kyte
October 03, 2003 - 8:06 am UTC

your sendmail is running on the host "localhost"? 127.0.0.1??

Reply: Getting error when using JavaMail

Andrew, October 03, 2003 - 9:33 am UTC

Yes, I tested on my PC with local host 127.0.0.1.
Is it OK for this JavaMail setting? Do I need to set up some thing else for the local host?

Thanks.

Tom Kyte
October 03, 2003 - 10:10 am UTC

should work OK i suppose. i'm not an smtp/java expert by anymeans. this is simply saying "the connection didn't work -- we tried"

you did do the grants right? using dbms_java??

Reply: Getting error when using JavaMail

Andrew, October 04, 2003 - 9:54 pm UTC

Hello Tom,

It worked.... I found the error in the Java stored procedure, fixed, and recompiled in database and the javamail api works fine.

Thank you very much.

ORA-03113 while calling utl_smtp.open_connection

Mohan, October 10, 2003 - 2:12 am UTC

When I call the function UTL_SMTP.OPEN_CONNECTION from a PL/SQL block gives the error ORA-03113: end-of-file on communication channel. How to catch the exception here.

Tom Kyte
October 10, 2003 - 8:10 am UTC

ora 3113 sort of means "bamm, your dead, game over player one, do not pass go, do not collect $200"

Your session is over.

Please contact support for this one.

most useful

appreciative fan, October 13, 2003 - 9:12 am UTC

Tom,

Been using this for awhile, and keep coming back to this link to find this procedure when it is needed in different places (since I don't keep it in my shirt pocket).

The package spec and package body for the send procedure are out of sync now though. default NULLS that are present in the body are missing from the spec on two or three of the attributes.

Tom Kyte
October 13, 2003 - 11:58 am UTC

they've always been like that :)

it just wasn't a problem until you upgraded to 9i! I had a bug that was OK in 8i, not in 9i. Just remove the defaults.

Error Encountered

Anirudh Sharma, October 21, 2003 - 11:20 am UTC

Hi Tom,
I encountered the following error while trying to send the mail through java.
anirudh@DW9I01T.US.ORACLE.COM 9.2> ed
Wrote file afiedt.buf

1 declare
2 ret_code number;
3 begin
4 for i in (select attachment from mailattachment )
5 loop
6 ret_code := send(
7 p_from => 'anirudhs@noida.hcltech.com',
8 p_to => 'anirudhs@noida.hcltech.com',
9 p_cc => null,
10 p_bcc => NULL,
11 p_subject => 'testing',
12 p_body => 'JAI HIND',
13 p_smtp_host => 'exch-01.noida.hcltech.com',
14 p_attachment_data => i.attachment,
15 p_attachment_type => 'text/plain',
16 p_attachment_file_name => 'hello.txt');
17 if ret_code = 1 then
18 dbms_output.put_line ('Successfully sent message...');
19 else
20 dbms_output.put_line ('Failed to send message...');
21 end if;
22 end loop;
23* end;
anirudh@DW9I01T.US.ORACLE.COM 9.2> /
javax.mail.NoSuchProviderException: smtp
at javax.mail.Session.getService(Session.java:750)
at javax.mail.Session.getTransport(Session.java:689)
at javax.mail.Session.getTransport(Session.java:632)
at javax.mail.Session.getTransport(Session.java:612)
at javax.mail.Session.getTransport(Session.java:667)
at javax.mail.Transport.send0(Transport.java:154)
at javax.mail.Transport.send(Transport.java:80)
at mail.send(mail.java:86)
Failed to send message...

PL/SQL procedure successfully completed.
------------------------------------------------------------------------------------------------------------------------
I tried to exclude Oracle from this and do the process using java itself. Wrote follo code in java but it gave the same error:
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

public class MailJava
{

public static void send(String mailserver,String subject ,String to[], String from, String messageText) throws AddressException, MessagingException
{
try
{
Properties mailProps = new Properties();
mailProps.put("mail.smtp.host", mailserver);
//mailProps.put("mail.debug", true);
Session mailSession = Session.getDefaultInstance(mailProps, null);
//mailSession.setDebug(true);
// Construct addresses

int toCount = to.length;
InternetAddress[] toAddrs = new InternetAddress[toCount];
for (int i = 0; i < toCount; ++i)
{
toAddrs[i] = new InternetAddress(to[i]);
}
InternetAddress fromAddr = new InternetAddress(from);
// Create and initialize message
Message message = new MimeMessage(mailSession);
message.setFrom(fromAddr);
System.out.println("30::"+Message.RecipientType.TO);
message.setRecipients(Message.RecipientType.TO, toAddrs);
System.out.println("35::"+subject);
message.setSubject(subject);
System.out.println("40::"+messageText.toString());
message.setContent(messageText.toString(), "text/plain");

// Send message
Transport.send(message);
}
catch(Exception e)
{
System.out.println(e);
}
}

public static void main(String[] args)
{
//MailJava.send(exch-01.noida.hcltech.com,"testSubject","anirudhs@noida.hcltech.com","From","","","Go_to_Hell","I****Love****You","exch-01.noida.hcltech.com","text/plain","anything.zip");
String too[] = {"anirudhs@noida.hcltech.com"};
try{
MailJava.send("EXCH-01","testSubject",too,"From","Error report");
}
catch(Exception e){System.out.println(e);}
}
}
--------------------------
-------------------------

D:\temp\activation8i>javac MailJava.java

D:\temp\activation8i>javac MailJava.java

D:\temp\activation8i>java MailJava
30::To
35::testSubject
40::Error report
javax.mail.NoSuchProviderException: smtp

D:\temp\activation8i>javac MailJava.java

D:\temp\activation8i>java MailJava
30::To
35::testSubject
40::Error report
javax.mail.NoSuchProviderException: smtp
------------------------
--------------------------
Please throw some light on what the problem could actually be.
Thanks,
Anirudh





Tom Kyte
October 21, 2003 - 5:10 pm UTC

well, that would be a java/smtp question. apparently, you don't have an smtp server at that hostname.

Sending Email Raw data

Vikas Sharma, October 22, 2003 - 3:15 pm UTC

Hi Tom,

I am sorry if i am posting this review at a wrong place.

I am trying to send mail using utl_smtp. I am not using the javamail api. I have writtena code using utl_smtp and setting up the MIME headers to send the text, html and any text files succesfully.

But i am facing problem in sending the birary file. I have set the mimie headers, i getting my file data send to mail server also but when i try to download the file it download with junk raw data.

To send the binary attachments i am doing the following things.
1. setting the mime headers to

--abs2sc3d74F7A1CD

Content-Type: application/octet
Content-Disposition: attachment; filename="mail.doc"
Content-Description: test-part-2
Content-Transfer-Encoding:base64

2. After setting the header i read the content of my file "mail.doc" and load the content to a blob using dbms_lob.loadfromfile. so now i have the content of the file into a blob. now i am using the following peice of code to write the blob data on SMTP

======================
l_offset := 1;
l_ammount := 57;
while l_offset < dbms_lob.getlength(l_blob) loop
utl_smtp.write_raw_data(l_connection,
(utl_encode.base64_encode(utl_raw.cast_to_raw(dbms_lob.substr(l_blob,l_ammount,l_offset)))));
l_offset := l_offset + l_ammount ;
l_ammount := least(57,dbms_lob.getlength(l_blob) - l_ammount);
end loop;
utl_smtp.write_data(l_connection,end_boundary); -- writing end boundary

=================================================

I am not sure is this the correct way of doing it. I have the data into a BLOB Do i need to cast in raw before i use utl_smtp.write_raw_data.?

If i cast to raw it using
(utl_smtp.write_raw_data(l_connection,
(utl_encode.base64_encode(utl_raw.cast_to_raw(dbms_lob.substr(l_blob,l_ammount,l_offset)))));

then the result of the content of files are like
===============================
Content-Transfer-Encoding:base64

RDBDRjExRTBBMUIxMUFFMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
M0UwMDAzMDBGRUZGMDkwMDA2MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDAwMDAw
MjEwMDAwMDAwMDAwMDAwMDAwMTAwMDAwMjMwMDAwMDAwMTAwMDAwMEZFRkZGRkZGMDAwMDAwMDAyMDAwMDAwMEZG

=================

If i dont use the use utl_raw.cast_to_raw ie using
utl_smtp.write_raw_data(l_connection,
(utl_encode.base64_encode(dbms_lob.substr(l_blob,l_ammount,l_offset))));

then the result are as follows

===============
Content-Transfer-Encoding:base64

0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAA
IQAAAAAAAAAAEAAAIwAAAAEAAAD+////AAAAACAAAAD/////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
=================

Pl suggest what i am doing wrong. i think somting is wrong when i am doing conversion of blob to raw.

Regards,

Vikas Sharma

Tom Kyte
October 22, 2003 - 6:23 pm UTC

sorry -- i don't know myself how to mime encode an entire email. I took the easy way out and borrowed the code from sun.

I would suggest the same to you! Its a nightmare trying to encode that junk.

UTL_SMTP with raw data

Vikas Sharma, October 22, 2003 - 7:27 pm UTC

Hi Tom,

Thanks For the reply.

I tried the Java API approach earlier also but it did not worked out. Recently I tried again but getting error

declare
ret_code number;
begin
for i in (select filename from mailattachments)
loop
ret_code := send(
p_from => 'vikas03@acme.com',
p_to => 'vsharma012@hotmail.com',
p_cc => NULL,
p_bcc => NULL,
p_subject => 'Use the attached Zip file',
p_body => 'to send email with attachments....',
p_smtp_host => 'mtlweb',
p_attachment_data => i.filename,
p_attachment_type => 'application/winzip',
p_attachment_file_name => 'ld_mem_banks.zip');
if ret_code = 1 then
dbms_output.put_line ('Successfully sent message...');
else
dbms_output.put_line ('Failed to send message...');
end if;
end loop;
end;
/
javax.mail.SendFailedException: Sending failed;
nested exception is:
class javax.mail.MessagingException: IOException while sending message;
nested exception is:
javax.activation.UnsupportedDataTypeException: no object DCH for MIME type multipart/mixed;
boundary="----=_Part_1_-909169289.1066049169595"
at javax.mail.Transport.send0(Transport.java:218)
at javax.mail.Transport.send(Transport.java:80)
at mail.send(mail:86)
Failed to send message...

PL/SQL procedure successfully completed.

i posted the error earlier also see above.
So i thought i will go for mime approach. And try with that.

Can you pl suggest me why i am encounter the above error my database is 8i(8.1.7). I loaded the mailapi version javamail 1.3 and frame work jaf-1.0.2 on sys account using your guide lines.

Btw pl tell me how can i use the blob data with "utl_smtp.write_raw_data" i am doing as following :

utl_smtp.write_raw_data(l_connection,
(utl_encode.base64_encode(utl_raw.cast_to_raw(dbms_lob.substr(l_blob,l_ammount,l_offset)))));

Is this correct?

Thanks & Regards

Vikas Sharma

Tom Kyte
October 22, 2003 - 7:42 pm UTC

i'll have a java dude take a look see and if he has any advice, will follow up.

base64 encoding -- as I remember it takes 3 bytes to store 2 or something like that. probably a boundary value condition, not sure that you can just "substr" like that and encode chunks. (this is why this becomes "hard". you have learn all about b64 encoding, something I haven't looked at in years myself)

and he says (the java guy)

Can you ask them to send a description of their table named "mailattachments". I wonder why they are setting the "filename" column to the actual data.

Also, it's looking for a data handler for "multipart/mixed" but I wonder why they are trying to attach that type to a mail message.

Even though he said he followed your instructions, I'd still like to see exactly how they loaded the the mail.jar and activation.jar

API Error

Vikas Sharma, October 22, 2003 - 8:02 pm UTC

Hi Tom,

Thanks,

If you want i can send you the complete description how i loaded classes and what error (output of loadjava) i got earlier by Email. It is not big abt 7k zip file.

Actually when i tried to load mail.zar on sys using loadjava i received few errors but then again i tried for second time, i did NOT get any error.

But my loadjava of activation.zar was finished with out any error on sys.

Thanks And Regards

Vikas Sharma


JavaMail on 9.2.0.4?

Doyle Freeman, October 23, 2003 - 10:53 am UTC

Is javamail still the best way to send an email with large attachments from pl/sql?
--
To be more clear about my specific issue.
--
I am creating an app with html db (love it by the way).
--
The user is able to select a file from their client machine and upload it. I then want to email that file to another party after I have done some validation on it thru pl/sql. I have a pl/sql package that gets fired after the file is uploaded that is reading the blob and verifying some business rules. If all of the business rules pass, then I want to email the blob as an attachment to another party.
--
Would you use the javamail through pl/sql to accomplish this, or is there a better way now?
--
Thanks

Tom Kyte
October 23, 2003 - 1:03 pm UTC

yes. it is the best way (until 10g)

java mail -- it is the best way.

Sending CLOB/BLOB with javamail

paul, October 23, 2003 - 11:02 am UTC

I dont do this with UTL_SMTP but we do it with javamail if you want to go back to that approach.

Here is some background.
a GTT gets populated with a list of external files and/or blobs, and/or clobs to attach to mail,
-we figure out mimetype based on extension.
-we use send_as_name to allow user to change filename of source document while sending.

the Java reads the GTT and for each record in resultset determines if File/Blob/Clob
[..]
if (rset.getString("file_type").equals("BLOB"))
{
MimeBodyPart mbp = new MimeBodyPart();
mbp.setDisposition(Part.ATTACHMENT);
mbp.setFileName(rset.getString("send_as_name"));
mbp.setDataHandler
(new DataHandler(new BLOBDataSource(rset.getBlob ("blob_data") , set.getString "mime_type"))));
mp.addBodyPart(mbp);
}
[..]
BLOBDatasource simply returns a binaryDatastream like so...
static class BLOBDataSource implements DataSource
{
private java.sql.Blob data;
private String type;
BLOBDataSource(java.sql.Blob data, String type)
{
this.type = type;
this.data = data;
}
public InputStream getInputStream() throws IOException
{
try
{
if(data == null)
throw new IOException("No data.");
return data.getBinaryStream();
} catch(SQLException e)
{
throw new
IOException("Cannot get binary input stream from BLOB.");
}
}
public OutputStream getOutputStream() throws IOException
{
throw new IOException("Cannot do this.");
}
public String getContentType()
{
return type;
}
public String getName()
{
return "BLOBDataSource";
}
}

Then we add the mp to the msg
msg.setContent(mp);

This was cobbled together from code here at asktom and also on OTN.
It will do fileattachments from o/s BLOBS (binarystream) and CLOBS (asciistream)

It might be easier to do the binary stuff this way than with CAST

Thanks Paul

A reader, October 23, 2003 - 12:11 pm UTC

Does anybody have any code for this, strictly using PL/SQL with javamail?
Sorry, reading java code is not my strength.

Tom Kyte
October 23, 2003 - 1:21 pm UTC

umm, yes, the original answer above is strictly using plsql with javamail. all of the code is there.

Best way until 10g?

Doyle Freeman, October 23, 2003 - 3:12 pm UTC

Just curious. What will be the best way with 10g?

Tom Kyte
October 23, 2003 - 7:20 pm UTC

UTL_MAIL :)

plsql api that supports attachments.


PROCEDURE send_attach_varchar2(
sender IN VARCHAR2 CHARACTER SET ANY_CS,
recipients IN VARCHAR2 CHARACTER SET ANY_CS,
cc IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
bcc IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
subject IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
message IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
mime_type IN VARCHAR2 CHARACTER SET ANY_CS
DEFAULT 'text/plain; charset=us-ascii',
priority IN PLS_INTEGER DEFAULT 3,
attachment IN VARCHAR2 CHARACTER SET ANY_CS,
att_inline IN BOOLEAN DEFAULT TRUE,
att_mime_type IN VARCHAR2 CHARACTER SET ANY_CS
DEFAULT 'text/plain; charset=us-ascii',
att_filename IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL);

PROCEDURE send_attach_raw(
sender IN VARCHAR2 CHARACTER SET ANY_CS,
recipients IN VARCHAR2 CHARACTER SET ANY_CS,
cc IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
bcc IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
subject IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
message IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL,
mime_type IN VARCHAR2 CHARACTER SET ANY_CS
DEFAULT 'text/plain; charset=us-ascii',
priority IN PLS_INTEGER DEFAULT 3,
attachment IN RAW,
att_inline IN BOOLEAN DEFAULT TRUE,
att_mime_type IN VARCHAR2 CHARACTER SET ANY_CS
DEFAULT 'application/octet',
att_filename IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL);


POP3

Praveen Sehgal, November 16, 2003 - 12:03 am UTC

Is there ANY way to retreive email directly into the database?

Tom Kyte
November 16, 2003 - 10:38 am UTC

load the java mail apis in there, and yes, you can read email.

or, if you use the collaboration suite, the database is email.

Retriving Mail IN 10g

vikas Sharma, November 19, 2003 - 9:02 pm UTC

Hi Tom,

Just curios to know that can we retrive the eamil to database using 10g.

Thanks,

Regards

Vikas Sharma

Tom Kyte
November 21, 2003 - 3:35 pm UTC

sure, just like you can in 9i, 8i -- you load the java mail API and retrieve it, store it, do whatever you like with it.

Error occurs while using UTL_SMTP

Ken, November 26, 2003 - 5:05 pm UTC

Hi Tom,

The solution is very helpful, but when I tried it, got some error messages:

SQL> begin
  2      pk_mail.send
  3      ( 'kchiang@toronto.bata.com',
  4        'kchiang@TORONTO.BATA.COM',
  5        'This is a testing mail',
  6        'Hello Ken, this is a testing mail'  );
  7  end;
  8  /

begin
*
ERROR at line 1:
ORA-29279: SMTP permanent error: 550 Unable to relay for kchiang@toronto.bata.com
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 98
ORA-06512: at "SYS.UTL_SMTP", line 240
ORA-06512: at "ADP6_ADMIN.PK_MAIL", line 51
ORA-06512: at line 2

What could be the possible reason and solution to it?  Please help!
 

Tom Kyte
November 27, 2003 - 10:21 am UTC

your smtp server is not configured to be a relay, it is not allowed to forward mail.

either

a) find someone who knows how to configure smtp and reconfigure your server to permit relays

b) use another smtp server.

Ken, November 27, 2003 - 1:29 pm UTC

Hi Tom,

Don't worry, my problem has been resolved, the problem was due to the wrong SMTP mail server name.

Thank you.



Sending Files as attachment

Jatinder, December 05, 2003 - 5:30 pm UTC

Hi Tom,

Just wanted to let you know that there's some information on TechNet that talks about using UTL_SMTP for sending emails with attachments.

</code> http://otn.oracle.com/sample_code/tech/pl_sql/htdocs/Utl_Smtp_Sample.html <code>

I am not sure if I follow how can I attach a document with the email. Basically, what I want to do is that we have a repositary of thousands of documents and the user can pick the document they want to have. Upon selection, the program should be able to email the selected documents to the user. Can you please let me know how I can achieve that using UTL_SMTP package.

Thanks in advance.

Tom Kyte
December 06, 2003 - 8:56 am UTC

i don't use utl_smtp for attachements, really hard.

i use the java mail api, demonstrated above. you send it a blob and away she goes.

utl_smtp

Ruben, February 07, 2004 - 3:16 pm UTC

Tom, How we can accomplish to send text to wireless
devices such as a mobile or pager?
It is possible via UTL_SMTP?

Thanks a lot for you reply.

Tom Kyte
February 07, 2004 - 3:52 pm UTC

sure, if you can email your stuff right now (like phone_number@skytell.com works) it is sort of obvious how to do it.

If you cannot, you might need something like 9iAS wireless that does SMS and other protocols.

Email Package

Steven Foskett, February 13, 2004 - 1:18 pm UTC

Hi Tom:

This was extremly straight forward and to the point. I was able to use your example and implement it very quickly.

Great Work

A reader, February 28, 2004 - 5:30 am UTC

Thanks a lot Tom....The examples were great

not compiling in 8.1.7.4 but compiles in 9.2.0.4.0

seekanth gadhiraju, March 11, 2004 - 9:53 am UTC

Based on you Java expample i wrote the following.  But it compiles fine and also works fine in 9.2.0.4.0 but when i try to compile in 8.1.7.4 it compile with errors here are the details.

My Code
-------


SQL> select version from v$instance;

VERSION                                                    
----------------- 
9.2.0.4.0                       

SQL> create or replace and compile
  2      java source named "gsijavamail"
  3      as
  4      import java.io.*;
  5      import java.sql.*;
  6      import java.util.Properties;
  7      import java.util.Date;
  8      import javax.activation.*;
  9      import javax.mail.*;
 10     import javax.mail.internet.*;
 11     import oracle.sql.*;
 12     public class gsijavamail
 13     {
 14   public static oracle.sql.NUMBER send(String host,
 15          String to,
 16          String from,
 17          String cc,
 18          String bcc,
 19          String RtnRcpt,
 20          String RtnPath,
 21          String ReplyTo,
 22          String priority,
 23          String Subject,
 24          String text,
 25          String filename)
 26   throws AddressException, SendFailedException, MessagingException{
 27   int rc = 0;
 28   try {
 29   Properties properties = System.getProperties();
 30   properties.put("mail.smtp.host",host);
 31   Session session = Session.getInstance(properties,null);
 32   MimeMessage message = new MimeMessage(session);
 33  
 34   MimeBodyPart attachment = new MimeBodyPart();
 35   Multipart mp = new MimeMultipart();
 36   MimeBodyPart mtxt = new MimeBodyPart();
 37   mtxt.setContent(text,"text/html");
 38   mp.addBodyPart(mtxt);
 39  
 40   message.setFrom(new InternetAddress(from));
 41   message.setRecipients(Message.RecipientType.TO,InternetAddress.parse(to));
 42   message.setSubject(Subject);
 43   message.setText(text);
 44   message.setSentDate(new Date());
 45  
 46   if (priority != null)
 47   {
 48    message.addHeader("X-Priority", priority);
 49   }
 50   if (priority == "1")
 51   {
 52    message.addHeader("Priority", "Urgent");
 53    message.addHeader("Importance", "high");
 54   }
 55  
 56   if (cc != null)
 57   {
 58    message.setRecipients(Message.RecipientType.CC,InternetAddress.parse(cc));
 59   }
 60  
 61   if (bcc != null)
 62   {
 63    message.setRecipients(Message.RecipientType.BCC,InternetAddress.parse(bcc));
 64   }
 65  
 66   if (RtnRcpt != null)
 67   {
 68    message.addHeader("Return-Receipt-To:",RtnRcpt);
 69   }
 70   if (RtnPath != null)
 71   {
 72    message.addHeader("Return-Path:", RtnPath);
 73   }
 74   if (ReplyTo != null)
 75   {
 76    message.addHeader("Reply-To:", ReplyTo);
 77   }
 78  
 79   if (filename != null )
 80   {
 81    File f = new File(filename);
 82    FileDataSource fds = new FileDataSource(f);
 83    attachment.setDataHandler(new DataHandler(new FileDataSource(f)));
 84    attachment.setFileName(fds.getName());
 85    mp.addBodyPart(attachment);
 86   }
 87  
 88   message.setContent(mp);
 89   Transport.send(message);
 90   rc = 1;
 91   } catch (Exception e)
 92    {rc = 0;
 93    }
 94    finally {
 95             return new oracle.sql.NUMBER(rc);
 96            }
 97  
 98   }
 99  }
100  
101  /

Java created.

in 8.1.7.4
--------
SQL> select version from v$instance;

VERSION                                                                         
-----------------                                                               
8.1.7.4.1                                                                       

SQL> create or replace and compile
  2      java source named "gsijavamail"
  3      as
  4      import java.io.*;
  5      import java.sql.*;
  6      import java.util.Properties;
  7      import java.util.Date;
  8      import javax.activation.*;
  9      import javax.mail.*;
 10     import javax.mail.internet.*;
 11     import oracle.sql.*;
 12     public class gsijavamail
 13     {
 14   public static oracle.sql.NUMBER send(String host,
 15          String to,
 16          String from,
 17          String cc,
 18          String bcc,
 19          String RtnRcpt,
 20          String RtnPath,
 21          String ReplyTo,
 22          String priority,
 23          String Subject,
 24          String text,
 25          String filename)
 26   throws AddressException, SendFailedException, MessagingException{
 27   int rc = 0;
 28   try {
 29   Properties properties = System.getProperties();
 30   properties.put("mail.smtp.host",host);
 31   Session session = Session.getInstance(properties,null);
 32   MimeMessage message = new MimeMessage(session);
 33  
 34   MimeBodyPart attachment = new MimeBodyPart();
 35   Multipart mp = new MimeMultipart();
 36   MimeBodyPart mtxt = new MimeBodyPart();
 37   mtxt.setContent(text,"text/html");
 38   mp.addBodyPart(mtxt);
 39  
 40   message.setFrom(new InternetAddress(from));
 41   message.setRecipients(Message.RecipientType.TO,InternetAddress.parse(to));
 42   message.setSubject(Subject);
 43   message.setText(text);
 44   message.setSentDate(new Date());
 45  
 46   if (priority != null)
 47   {
 48    message.addHeader("X-Priority", priority);
 49   }
 50   if (priority == "1")
 51   {
 52    message.addHeader("Priority", "Urgent");
 53    message.addHeader("Importance", "high");
 54   }
 55  
 56   if (cc != null)
 57   {
 58    message.setRecipients(Message.RecipientType.CC,InternetAddress.parse(cc));
 59   }
 60  
 61   if (bcc != null)
 62   {
 63    message.setRecipients(Message.RecipientType.BCC,InternetAddress.parse(bcc));
 64   }
 65  
 66   if (RtnRcpt != null)
 67   {
 68    message.addHeader("Return-Receipt-To:",RtnRcpt);
 69   }
 70   if (RtnPath != null)
 71   {
 72    message.addHeader("Return-Path:", RtnPath);
 73   }
 74   if (ReplyTo != null)
 75   {
 76    message.addHeader("Reply-To:", ReplyTo);
 77   }
 78  
 79   if (filename != null )
 80   {
 81    File f = new File(filename);
 82    FileDataSource fds = new FileDataSource(f);
 83    attachment.setDataHandler(new DataHandler(new FileDataSource(f)));
 84    attachment.setFileName(fds.getName());
 85    mp.addBodyPart(attachment);
 86   }
 87  
 88   message.setContent(mp);
 89   Transport.send(message);
 90   rc = 1;
 91   } catch (Exception e)
 92    {rc = 0;
 93    }
 94    finally {
 95             return new oracle.sql.NUMBER(rc);
 96            }
 97  
 98   }
 99  }
100  
101  /

Warning: Java created with compilation errors.

SQL> show err
Errors for JAVA SOURCE gsijavamail:

LINE/COL ERROR                                                                  
-------- -----------------------------------------------------------------      
0/0      gsijavamail:23: Class AddressException not found in throws.            
0/0      gsijavamail:28: Class Session not found.                               
0/0      gsijavamail:28: Class Session not found.                               
0/0      gsijavamail:28: Undefined variable or class name: Session              
0/0      gsijavamail:29: Class MimeMessage not found.                           
0/0      gsijavamail:29: Class MimeMessage not found.                           
0/0      gsijavamail:31: Class MimeBodyPart not found.                          
0/0      gsijavamail:31: Class MimeBodyPart not found.                          
0/0      gsijavamail:32: Class Multipart not found.                             
0/0      gsijavamail:32: Class MimeMultipart not found.                         
0/0      gsijavamail:33: Class MimeBodyPart not found.                          

LINE/COL ERROR                                                                  
-------- -----------------------------------------------------------------      
0/0      gsijavamail:33: Class MimeBodyPart not found.                          
0/0      gsijavamail:49: Variable message may not have been initialized.        
0/0      gsijavamail:55: Variable message may not have been initialized.        
0/0      gsijavamail:60: Variable message may not have been initialized.        
0/0      gsijavamail:65: Variable message may not have been initialized.        
0/0      gsijavamail:69: Variable message may not have been initialized.        
0/0      gsijavamail:73: Variable message may not have been initialized.        
0/0      gsijavamail:79: Class FileDataSource not found.                        
0/0      gsijavamail:79: Class FileDataSource not found.                        
0/0      gsijavamail:85: Variable message may not have been initialized.        
0/0      gsijavamail:86: Undefined variable or class name: Transport            

LINE/COL ERROR                                                                  
-------- -----------------------------------------------------------------      
0/0      Info: 22 errors                                                        
SQL> spool off;
                             

Tom Kyte
March 11, 2004 - 1:55 pm UTC

you didn't load the java packages into the db for 8i

How to load

sreekanth gadhirjau, March 11, 2004 - 2:12 pm UTC

tom,

on 9.2.0.4.0 i did not load any classes explicitly. I just compiled. here is what happend.

we are running oracle 11i application on 8.1.7.4. We are in the middle of upgrading the database to 9i release 2. So we cloned the test system from production 11i system and then upgraded the database to 9i. now this one compiles in 9i but not in 8i.

Do i need to download the javamail api from sun site to load these classes? Please tell me how to load these classes.

thanks
sreekanth.g




Tom Kyte
March 11, 2004 - 2:16 pm UTC

see above, the above example (step by steps) were developed for 8i. the step by step are there in the original answer.

error while loading javaclass with loadjava

sreekanth gadhiraju, March 12, 2004 - 11:53 am UTC

tom,

when try to load mailapi using the loadjava it is giving the following error

C:\mailapi\tmp>loadjava -u SYS/password0@NINE -o -r -v -f -noverify -synonym -g
public mail8i.zip >output.txt
arguments: '-u' 'SYS/password@NINE' '-o' '-r' '-v' '-f' '-noverify' '-synonym'
'-g' 'public' 'mail8i.zip'
creating : resource META-INF/javamail.charset.map
SQL Error while connecting with oci8 driver to NINE: ORA-01031: insufficient pri
vileges

exiting : could not open connection

thanks
sreekanth.g

Tom Kyte
March 12, 2004 - 4:47 pm UTC

ctl-f 1031 <enter>

smtp error while sending an email

Eugene, March 12, 2004 - 2:02 pm UTC

Hi Tom,
Hope you can tell me why I may get this error?

CREATE OR REPLACE PROCEDURE Ep_Sendmail_1 
                                                (p_sender IN VARCHAR2,
                                          p_recipient IN VARCHAR2,
                                          p_message   IN VARCHAR2)
AS
     l_mailhost VARCHAR2(255) := '192.168.1.6';
     l_mail_conn utl_smtp.connection;

BEGIN
     l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
     utl_smtp.helo(l_mail_conn, l_mailhost);
     utl_smtp.mail(l_mail_conn, p_sender);
     utl_smtp.rcpt(l_mail_conn, p_recipient);
     utl_smtp.open_data(l_mail_conn );
     utl_smtp.write_data(l_mail_conn, p_message);
     utl_smtp.close_data(l_mail_conn );
     utl_smtp.quit(l_mail_conn);
END Ep_Sendmail_1;
/

SQL> begin
  2  ep_sendmail_1('epipko@unionbay.com',
  3  'epipko@unionbay.com', 
  4  'Hello there');
  5  end;
  6  /

PL/SQL procedure successfully completed.

Then our email program gives us following errors:

X-Mail-Format-Warning: Bad RFC2822 header formatting in MAIL FROM:epipko@unionbay.com
X-Mail-Format-Warning: Bad RFC2822 header formatting in RCPT TO:epipko@unionbay.com
X-GWIA: Thu, 11 Mar 2004 13:41:45 -0800; 192.168.1.6([192.6.1.80])
Received: from 192.168.1.6
 ([192.6.1.80])
 by unionbay.com; Thu, 11 Mar 2004 13:41:45 -0800
X-Mail-Format-Warning: Bad RFC2822 header formatting in Hello
 

Tom Kyte
March 12, 2004 - 7:52 pm UTC

what "email" program?? I mean, how does an email program fit into this?

what is ctl-f 1031 <enter>

sreekanth gadhiraju, March 13, 2004 - 10:12 am UTC

tom,

can you please explain ctl-f 1031 <enter> ?

thanks
sreekanth.g

Tom Kyte
March 13, 2004 - 10:22 am UTC

search for 1031 on this page -- its been asked and answered in the past.

ctl-f should pop up the little "search" dialog
1031 is the number you want to search for
<enter> will do it (the search)....




e mail

alex, March 23, 2004 - 3:42 pm UTC

Tom

I am having trouble in tacking the undelivered mails using SMTP.
Can you please advise me who can we tracke these

Tom Kyte
March 24, 2004 - 8:11 am UTC

when I send an email using utl_smtp from asktom

and it is not deliverable

it comes back to me, in my inbox. The error will goto whomever "sent" it (you can use an errors-to: record as well, or something like that, you'd just google the smtp protocol and see what options you have)

Soooo, whatever you are using in the from should be getting the "bounce". I sure do :)

problem getting activation8i.zip to resolve

Jim, April 07, 2004 - 2:31 pm UTC

Hi Tom!

I'm running 8i standard (8.1.5.0.0 w/ the java option) on win2k and am having a heck of a time trying to get through the first step of getting the uncompressed archive to load successfully... here's my command and a trimmed output

>loadjava -u sys/system -o -r -v -f -synonym -g public activation8i_uncomp.zip
initialization complete
loading : com/sun/activation/registries/LineTokenizer
creating : com/sun/activation/registries/LineTokenizer
.
. (all successful loads and creates)
.
loading : javax/activation/FileTypeMap
creating : javax/activation/FileTypeMap
resolver :
resolving: com/sun/activation/registries/LineTokenizer
resolving: javax/activation/ActivationDataFlavor
resolving: javax/activation/DataHandlerDataSource
Errors in javax/activation/DataHandlerDataSource:
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
com/sun/activation/registries/MailcapFile is already resolved
resolving: javax/activation/CommandInfo
Errors in javax/activation/CommandInfo:
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
resolving: javax/activation/DataHandler
Errors in javax/activation/DataHandler:
ORA-29534: referenced object SYS.javax/activation/CommandMap could not be re
solved
resolving: com/sun/activation/viewers/ImageViewer
Errors in com/sun/activation/viewers/ImageViewer:
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
.
. (lots of failed resolves)
.
resolving: javax/activation/FileTypeMap
Errors in javax/activation/FileTypeMap:
ORA-29534: referenced object SYS.javax/activation/MimetypesFileTypeMap could
not be resolved
synonym : com/sun/activation/registries/LineTokenizer
.
. (lots of successful create synonyms)
.
synonym : javax/activation/FileTypeMap
loadjava: 24 errors

you'll probably notice that i had to remove the -noverify option, my version of loadjava does not recognize it for some reason..

prior to this i've run initjvm.sql as well, ...

i've seen that you redirected a few ppl to email your java dude, i don't want to bother him but would it be cool to do so?

many thanks from the kid from MA that always asks you to sign your books/have your pic taken w/ me

-jim

utl_smtp

Andre de Jager, April 22, 2004 - 1:35 am UTC

No, I do not think that this helped me at all.

How do I send attachments using the utl_smtp package. I keep on getting the email message, but the attachment is a empty blank page with the following on the page:
attachment_file_name

My code:
Procedure adj_send_email_test as

CRLF CONSTANT varchar2(10) := utl_tcp.CRLF;
BOUNDARY CONSTANT varchar2(256) := '-----7D81B75CCC90D2974F7A1CBD';
FIRST_BOUNDARY CONSTANT varchar2(256) := '--'||BOUNDARY||CRLF;
LAST_BOUNDARY CONSTANT varchar2(256) := '--'||BOUNDARY||'--'||CRLF;
MULTIPART_MIME_TYPE CONSTANT varchar2(256) := 'multipart/mixed; boundary="'||BOUNDARY||'"';

conn utl_smtp.connection;
from_name varchar2(255) := 'André de Jager';
from_address varchar2(255) := 'andre.dejager@newname.co.za';
to_address varchar2(255) := 'andre.dejager@newname.co.za';
cc_address varchar2(255) := '';
subject varchar2(255) := 'Wilgers Visits';
mime_type varchar2(255) := 'text/html'; --'xls/csv';
attachment_file_name varchar2(2500) := 'c:\extracts\hosp\stats.htm'; --'stats.xls';
mailhost varchar2(255) := '172.27.0.250';

Procedure send_header(name in varchar2,
header in varchar2) is

begin
utl_smtp.write_data(conn, name||': '||header||CRLF);
End;

BEGIN

conn := utl_smtp.open_connection(mailhost);
utl_smtp.helo(conn,mailhost);
utl_smtp.mail(conn,'< '||from_address||' >');
utl_smtp.rcpt(conn,'< '||to_address||' >');
utl_smtp.open_data(conn);
send_header('From','"'||from_name||'" <'||from_address||'>');
send_header('To',''||to_address||'');
cc_address := to_address;
send_header('cc',''||cc_address||'');
send_header('Date',to_char (sysdate, 'dd Mon yy hh24:mi:ss')|| ' +1100');
send_header('Subject',subject);
send_header('Content-Type',MULTIPART_MIME_TYPE);

-- Close header section by a crlf on its own
utl_smtp.write_data(conn,CRLF);
utl_smtp.write_data(conn,'This is a multi-part message in MIME format.'||CRLF);

----------------------------------------
-- Send the main message text
----------------------------------------
-- mime header
utl_smtp.write_data(conn, FIRST_BOUNDARY);
send_header('Content-Type',mime_type);
utl_smtp.write_data(conn, CRLF);
utl_smtp.write_data(conn, '<html><body>see attachment</body></html>');
utl_smtp.write_data(conn, CRLF);

-- add the attachment
utl_smtp.write_data(conn, FIRST_BOUNDARY);
send_header('Content-Type',mime_type);
send_header('Content-Disposition','attachment; filename= '||attachment_file_name);
utl_smtp.write_data(conn, CRLF);
utl_smtp.write_data(conn, '<html><body>attachment_file_name</body></html>');
utl_smtp.write_data(conn, CRLF);

-- Close the message
utl_smtp.write_data(conn, LAST_BOUNDARY);

-- Close connection
utl_smtp.close_data(conn);
utl_smtp.quit(conn);

end;
/


Tom Kyte
April 22, 2004 - 7:33 am UTC

guess you got bored reading after the first paragraph or two?

<quote>
Loading and using the JavaMail API

In order to use the UTL_SMTP package, you must already have a Java enabled
database in Oracle8i. This is because UTL_SMTP relies on UTL_TCP and UTL_TCP in
turn is built on Java functions. (Remember, if you don't have a Java enabled
database you can use UTL_HTTP as described above to send simple emails). So, if
you are able to use UTL_SMTP, you must have a Java enabled database, we can go
to the Sun website and download their JavaMail API. This will give us the
ability to send much more complicated emails from the database; including
attachments.
The following is based on work performed by a coworker of mine,
Mark Piermarini who helps me out with lots of my Java issues.
</quote>

PLSQL Mail routine vs Java

Barry Chase, April 29, 2004 - 12:37 pm UTC

The article was very helpful, however it leaned towards JavaMail as the end all solution. Unfortunately, I am not at liberty to get that installed on our AIX platform here for a number of non-technical reasons.

Through some net scouring and laborious hours of effort of my own, I came up with a PLSQL solution which handles attachments (including binary) and produces formatted emails.

I would be happy to share it with the masses, but I don't know how to get it posted it here for others to use. I also have a PLSQL FTP solution, which contains binary support as well.

I have the code at my website, and I would post it here, but I don't want to be seen as posting inappropriate material in the forum.

Any suggestions on what I can do to share my code with others ?

Tom Kyte
April 29, 2004 - 12:43 pm UTC

just plug a URL in here -- it'll become a link. no worries on that.

Pure PLSQL solution for Email and FTP (both with binary support)

Barry Chase, April 30, 2004 - 10:52 am UTC

Thanks for letting me share this. Any feedback would be welcome.

I have been working on my package solutions for Email and FTP routines for close to a year now. I have posted my updates in the downloads area of my website

</code> http://www.mylxhq.com <code>

The initial code was gleened from the web from elsewhere, but I provide a number of enhancements that took the routines to the next level and made them production ready. Below are some sample scripts that can be used to test the packages. The mail package header needs to have your mail server inserted in it before you compile it though.

Assuming that you have have compiled in the FTP and Email Packages that I have prepared, you can then use the following sample script to email a text file and email a binary file.

/* Formatted on 2004/04/09 14:06 (Formatter Plus v4.8.0) */
DECLARE
l_rows NUMBER;
l_sql VARCHAR2 (32000);
p_status VARCHAR2 (32000);
p_error_msg VARCHAR2 (32000);
p_elapsed_time VARCHAR2 (100);
p_bytes_trans NUMBER;
p_trans_start DATE;
p_trans_end DATE;
l_blob BLOB;
l_blob_len NUMBER;
BEGIN
hum_mail_tools.mail_files
(from_name => 'admin@mylxhq.com'
, to_name => 'bsc7080mqc1@mylxhq.com'
, subject => 'MAIL_FILES :: Sample TXT file'
, MESSAGE => 'Local DB Server ascii attachment in email.'
, priority => 3
, filename1 => '/xfer/INTF0047/sample.txt'
, DEBUG => 0
);
--
l_blob :=
hum_mail_tools.get_local_binary_data (p_dir => '/xfer/INTF0047'
, p_file => 'sample.pdf');
l_blob_len := DBMS_LOB.getlength (l_blob);
hum_mail_tools.mail_files_binary
(from_name => 'admin@mylxhq.com'
, to_name => 'bsc7080mqc1@mylxhq.com'
, subject => 'TEST08APR2004'
, MESSAGE => 'Local DB Server binary attachment in email.'
, priority => 3
, filename => 'sample.pdf'
, binaryfile => l_blob
, DEBUG => 0
);
DBMS_OUTPUT.put_line ('fini');
END;

To perform FTP operations of PUT and GET, you can follow this sample script.


/* Formatted on 2004/04/09 12:35 (Formatter Plus v4.8.0) */
SET linesize 2000

DECLARE
p_status VARCHAR2 (32000);
p_error_msg VARCHAR2 (32000);
p_elapsed_time VARCHAR2 (100);
p_remote_path VARCHAR2 (2000);
p_local_path VARCHAR2 (2000);
p_hostname VARCHAR2 (100);
p_username VARCHAR2 (100);
p_password VARCHAR2 (100);
p_files VARCHAR2 (4000);
p_bytes_trans NUMBER;
p_trans_start DATE;
p_trans_end DATE;
lbok BOOLEAN;
lnfilescnt NUMBER := 0;
lnfiles_array hum_ps_parse.atoms_tabtype;
lnfiles_empty_array hum_ps_parse.atoms_tabtype;
t_files ftp_interface.t_ftp_rec;
p_failed CHAR (1) := 'N';
-- This could be put in the header of your package
p_debug CHAR (1) := 'N';
BEGIN
--
IF p_failed = 'N'
THEN
--
-- Lets setup our output header columns
--
-- To process a file as a different name use the # symbol
-- test.txt#test.txt20032801
-- Would be used if you wanted to send the file test.txt but copy to remote server as test.txt20032801
DBMS_OUTPUT.put_line ( RPAD ('FILENAME', 40)
|| ' | '
|| RPAD ('STATUS', 15)
|| ' | '
|| RPAD ('BYTES', 15)
|| ' | '
|| RPAD ('START TIME', 25)
|| ' | '
|| RPAD ('END TIME', 25)
|| ' | '
|| 'ERROR MESSAGE');
DBMS_OUTPUT.put_line (CHR (10));
--
-- Let us PUT a file
--
p_files := 'sample.doc#sample1.doc';
lbok :=
ftp_interface.put (p_localpath => 'localpath'
, p_filename => p_files
, p_remotepath => 'remotepath'
, p_username => 'username'
, p_password => 'password'
, p_hostname => 'server'
, v_status => p_status
, v_error_message => p_error_msg
, n_bytes_transmitted => p_bytes_trans
, d_trans_start => p_trans_start
, d_trans_end => p_trans_end
, p_port => 21
, p_filetype => 'BINARY'
);

IF lbok = TRUE
THEN
DBMS_OUTPUT.put_line ( RPAD (p_files, 40)
|| ' | '
|| RPAD (p_status, 15)
|| ' | '
|| RPAD (TO_CHAR (p_bytes_trans), 15)
|| ' | '
|| RPAD (TO_CHAR (p_trans_start
, 'YYYY-MM-DD HH:MI:SS')
, 25)
|| ' | '
|| RPAD (TO_CHAR (p_trans_end
, 'YYYY-MM-DD HH:MI:SS')
, 25)
|| ' | '
|| p_error_msg);

IF p_status <> 'SUCCESS'
THEN
p_failed := 'Y';
END IF;

DBMS_OUTPUT.put_line ( 'FTP PROCESS FAILED := '
|| p_failed);
ELSE
DBMS_OUTPUT.put_line (p_error_msg);
p_failed := 'Y';
DBMS_OUTPUT.put_line ( 'FTP PROCESS FAILED := '
|| p_failed);
END IF;

--
-- Let us GET a file
--
p_files := 'sample1.doc';
lbok :=
ftp_interface.get (p_localpath => 'localpath'
, p_filename => p_files
, p_remotepath => 'remotepath'
, p_username => 'username'
, p_password => 'password'
, p_hostname => 'server'
, v_status => p_status
, v_error_message => p_error_msg
, n_bytes_transmitted => p_bytes_trans
, d_trans_start => p_trans_start
, d_trans_end => p_trans_end
, p_port => 21
, p_filetype => 'BINARY'
);

IF lbok = TRUE
THEN
DBMS_OUTPUT.put_line ( RPAD (p_files, 40)
|| ' | '
|| RPAD (p_status, 15)
|| ' | '
|| RPAD (TO_CHAR (p_bytes_trans), 15)
|| ' | '
|| RPAD (TO_CHAR (p_trans_start
, 'YYYY-MM-DD HH:MI:SS')
, 25)
|| ' | '
|| RPAD (TO_CHAR (p_trans_end
, 'YYYY-MM-DD HH:MI:SS')
, 25)
|| ' | '
|| p_error_msg);

IF p_status <> 'SUCCESS'
THEN
p_failed := 'Y';
END IF;

DBMS_OUTPUT.put_line ( 'FTP PROCESS FAILED := '
|| p_failed);
ELSE
DBMS_OUTPUT.put_line (p_error_msg);
p_failed := 'Y';
DBMS_OUTPUT.put_line ( 'FTP PROCESS FAILED := '
|| p_failed);
END IF;
END IF;

DBMS_OUTPUT.put_line (CHR (10));
DBMS_OUTPUT.put_line ('FINI');
END;

To perform DELETEs and RENAMEs isn't much different. I have only tested the binary ftp support with zip files, and it works just fine. I haven't found an upper file size limit yet.

It is important to note that in order to handle binary files it requires some to setup Database Directories in Oracle which refer to physical drive locations. This gives Oracle the correct permissions to read files from the filesystem.

message as sms to mobile

Anurag, May 06, 2004 - 2:19 am UTC

Hi!,

Great information! How can I extend this facility as sms to multiple mobile nos.

thanks,

Tom Kyte
May 06, 2004 - 7:28 am UTC

send multiple mails?

sms

Anurag, May 06, 2004 - 8:52 am UTC

actually, I wanted to write event based triggers, and would like to send db acute problems(db server messages) on my senior and mine mobile as sms eg. instance crash, block corruption, locking etc. We are unable to work on its algorithm.



Tom Kyte
May 06, 2004 - 9:16 am UTC

use OEM (enterprise manager) -- it has such hooks.

otherwise, you will be scripting this yourself. figuring out how to talk to sms (easiest way for me is, well, email -- email my phone number a message).


virtually every off the shelf monitoring tool, of which there are hundreds, does this out of the box.

multiple email addresses in a variable doesn't seem to work

ht, May 09, 2004 - 3:08 am UTC

Tom,
I get this error when trying to use a variable that contains " 'a@y.com','b@y.com' ":

ERROR at line 1:
ORA-29279: SMTP permanent error: 553 malformed address:

As your example proves, hardcoding the array works fine:

pkg1.send_email
(
in_from_email => 'x@y.com',
in_from_alias => 'X <'x@y.com'>,
in_to => test_mail_pkg1.array
--'a@y.com','b@y.com', <-- works fine
(l_addresses), <-- doesn't work
in_cc => pkg1.array('c@y.com'),
in_bcc => pkg1.array(d@y.com'),
in_subject => 'this is the subject',
in_body => 'this is the body'
);

What am I missing here? I also reviewed your example that uses a cursor to loop through each address but:

1. I would like to have all email addresses shown in the "to:" label so the addressees know who else received the email.
2. My data is stored in the db as a string (a@y.com,b@y.com, ...).

TIA
ht

Tom Kyte
May 10, 2004 - 7:43 am UTC

you have to PARSE THE STRING into array elements -- each name gets a RCPT call.

a,b -> invalid emails

a
b

are "ok emails"..... You have to send an array, not a single string. if you want to send a single string, parse it in the lower level routines around the commas.

Sending a string (not an array) works fine.

ht, May 10, 2004 - 6:48 pm UTC


Basic question about using dbms_job inside of a trigger.

ht, May 14, 2004 - 2:53 pm UTC

Tom,
This is a very basic question. I'm trying to use dbms_job inside of a trigger to execute dbms_job. As you advised, this will prevent emails from being sent (using utl_smtp) before the update is commited.
I cannot figure out how to create the trigger using dbms_job and I'm sure it's something "basic" that I'm missing.


>connect scott/tiger
Connected.
>create or replace trigger emp_aru
2 after update on emp
3 for each row
4 declare
5 variable jobno number;
6 begin
7
8 -- create a job that will not send the email unless the update is committed.
9 dbms_job.submit
10 (
11 :jobno,
12 'scott.x'
13 );
14 end;
15 /

Warning: Trigger created with compilation errors.

>show errors;
Errors for TRIGGER EMP_ARU:

LINE/COL ERROR
-------- -----------------------------------------------------------------
2/17 PLS-00103: Encountered the symbol "NUMBER" when expecting one of
the following:
:= . ( @ % ; not null range default character
The symbol ":=" was substituted for "NUMBER" to continue.

8/9 PLS-00049: bad bind variable 'JOBNO'
>----------------------------------------------------------
>
>exit;
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production


Tom Kyte
May 15, 2004 - 12:24 pm UTC

do you have access to expert one on one Oracle? I have lots and lots and lots of examples in there (appendix on dbms_job and utl_smtp)

basically -- none of that is "trigger code", it looks like a mixture of sqlplus (variable, :x) and plsql.


I'm afraid to give you a code snippet here as there seems to be a misunderstanding of plsql vs sqlplus totally. I don't want to send you down the wrong path .

Email from PL/SQL - Basic question

A reader, June 11, 2004 - 6:58 am UTC

Hi

How do I find out mail host to send mail from PL/SQL?

Thanks


Tom Kyte
June 11, 2004 - 4:08 pm UTC

ask your system administrator??

utl_mail.send error on 10g

LC, June 29, 2004 - 12:27 pm UTC

Tom, any thoughts on why this won't work?

Your help is always appreciated.

_____________________________________
SQL> BEGIN 
  2  utl_mail.send (
  3  SENDER     => 'add1@mycompany.com', 
  4  RECIPIENTS => 'add2@mycompany.com', 
  5  SUBJECT    => 'test',
  6  MESSAGE    => 'test');
  7  end;
  8  /
BEGIN
*
ERROR at line 1:
ORA-29261: bad argument
ORA-06512: at "SYS.UTL_TCP", line 28
ORA-06512: at "SYS.UTL_TCP", line 257
ORA-06512: at "SYS.UTL_SMTP", line 116
ORA-06512: at "SYS.UTL_SMTP", line 139
ORA-06512: at "SYS.UTL_MAIL", line 228
ORA-06512: at "SYS.UTL_MAIL", line 350
ORA-06512: at line 2
 

Tom Kyte
June 29, 2004 - 4:26 pm UTC

did you:

....
You define the SMTP_OUT_SERVER parameter in the init.ora rdbms initialization file. However, if SMTP_OUT_SERVER is not defined, this invokes a default of DB_DOMAIN which is guaranteed to be defined to perform appropriately.

utl_mail.send sends, but...

LC, June 29, 2004 - 6:26 pm UTC

Thanks so much for your help. I added the parameter and it works now... well kinda. The message sends, but I get
<quote>
<=?WE8ISO8859P1?Q?
</quote>

appended to the front of the "SENDER", "RECIPIENTS", and "SUBJECT" and the "RECIPIENTS" are bc'd as well.

Thoughts on that?

Tom Kyte
June 29, 2004 - 7:45 pm UTC

the email client is supposed to handle that -- it is a standard way of encoding that information so it can be displayed correctly. what email client are you using?

email client

LC, July 01, 2004 - 12:00 pm UTC

I am using Novell GroupWise both C/S and web. My SMTP mail host is setup to deny relaying to outside addresses so I am unable to test other clients.

Tom Kyte
July 01, 2004 - 7:42 pm UTC

try a different client and see if it is because your client does not conform to the standard.

If not, you can always use utl_smtp and just "do it yourself", it is very easy (see above)

Empty Message

Reader, July 29, 2004 - 1:33 am UTC

Hi Tom,

I used the very basic example to send a mail,

********
CREATE OR REPLACE procedure send_mail(p_message in varchar2)
as
l_mailhost varchar2(200) := 'mail.mydomain.com';
p_sender  varchar2(200) := 'development@mydomain.com';
p_recipient  varchar2(200) := me@mydomain.com';
l_mail_conn utl_smtp.connection;
begin
l_mail_conn := utl_smtp.open_connection(l_mailhost,25);
utl_smtp.helo(l_mail_conn,l_mailhost);
utl_smtp.mail(l_mail_conn,p_sender);
utl_smtp.rcpt(l_mail_conn,p_recipient);
utl_smtp.open_data(l_mail_conn);
utl_smtp.write_data(l_mail_conn,p_message);
utl_smtp.close_data(l_mail_conn);
utl_smtp.quit(l_mail_conn);
end;
/
*********
SQL> exec send_mail('test');

but when I get the mail the message body contains 


<Message>
Error Reading Message or message with NULL body!!
</Message>

I get the same in both IE and Mozilla Firefox. One of my friend used the same code to send me the mail from his Mailserver and it comes just fine. So is there something wrong with my Mail Server?

Thanks 

Tom Kyte
July 29, 2004 - 11:26 am UTC

remove utl_smtp from the loop, test with telnet:


[tkyte@tkyte-pc tkyte]$ telnet hostname 25
Trying 138.1.161.112...
Connected to hostname
Escape character is '^]'.
220 rgmgw2.us.oracle.com ESMTP Sendmail Switch-3.1.4/Switch-3.1.0 - Ready at Thu, 29 Jul 2004 09:18:50 -0600 - Unauthorized Usage Prohibited.
helo hostname
250 rgmgw2.us.oracle.com Hello tkyte-pc.us.oracle.com [138.1.120.255], pleased to meet you
Help mail
214-2.0.0 MAIL FROM: <sender> [ <parameters> ]
214-2.0.0 Specifies the sender. Parameters are ESMTP extensions.
214-2.0.0 See "HELP DSN" for details.
214 2.0.0 End of HELP info
mail from: tkyte@oracle.com
250 2.1.0 tkyte@oracle.com... Sender ok
help rcpt
214-2.0.0 RCPT TO: <recipient> [ <parameters> ]
214-2.0.0 Specifies the recipient. Can be used any number of times.
214-2.0.0 Parameters are ESMTP extensions. See "HELP DSN" for details.
214 2.0.0 End of HELP info
rcpt to: tkyte@oracle.com
250 2.1.5 tkyte@oracle.com... Recipient ok
help data
214-2.0.0 DATA
214-2.0.0 Following text is collected as the message.
214-2.0.0 End with a single dot.
214 2.0.0 End of HELP info
data
354 Enter mail, end with "." on a line by itself
test
.

250 2.0.0 i6TFIoBF001928 Message accepted for delivery
quit
221 2.0.0 rgmgw2.us.oracle.com closing connection
Connection closed by foreign host.
[tkyte@tkyte-pc tkyte]$



you do the stuff in bold using your own email address and host.

Empty Message

Reader, July 29, 2004 - 11:35 pm UTC

Hi Tom,

I tried the said things, but I still get a mail to my account with
<Message>
Error Reading Message or message with NULL body!!
</Message>

So I tried from Oracle 10g with UTL_MAIL.SEND, and voila!! it worked just fine.I am able to get the Subject as well as the body of the mail properly, but using the same procedure from 10g also did not work. So now I am really up against the wall.
By the way my Oracle Version for the previous attempt was Oracle 9i Release 2,from a Linux and Windows Box(from where I am getting the Empty Message).
Any chances of solving the problem ?

Thanks and Regards

Tom Kyte
July 30, 2004 - 7:36 am UTC

if you did that with telnet and you got that -- problem is somewhere on your end -- with your smtp / email client setup. we've removed Oracle from the loop entirely and are just using standard, documented, reliable SMTP commands. sorry.

It is an excellent information but not useful to me

A reader, August 10, 2004 - 5:05 am UTC

It is an excellent information. But it is not useful to me. I am sending an email through oracle stored procedure but it doesn't support html formatting. When a mail goes uses find the html tags etc. in the mail

So How do I solve. I have tried hardly But yet didn't get success. So can you help earlies

Thanks

amol@skinternational.com


Tom Kyte
August 10, 2004 - 7:58 am UTC

search for

utl_smtp html

and see what you see

Oracle 8.0

Yogesh, August 19, 2004 - 4:37 am UTC

Does this specification / information applies to oracle 8.0? If not, then how can we send mail from oracle 8.0?

Tom Kyte
August 19, 2004 - 9:44 am UTC

it is very very difficult.

going into the way back machine.....

there is no utl_smtp in 8
there are no external procedures in 8
there are no java subroutines in 8

there is however utl_file and utl_http. so, what i've done in times gone by is:

a) use utl_file to create a uniquely named file with the email in it.
b) write a cgi-bin script that runs under the webserver that takes the name of the person to email to and the name of the file to email
c) send the mail from plsql via utl_http.request( '</code> http://127.0.0.1/cgi-bin/send_mail?p_name=....&p_file=.....' <code>);

I use 127.0.0.1 because the webserver must be running on the server (to be able to see the utl_file file) and I don't want just any john doe to be able to send email as if it was "oracle" on this machine.


You can also just do

a) use utl_file to create a uniquely named file that includes the target email address
b) use a cron job to periodically pick up all "spooled" files and send them.

Randy, August 19, 2004 - 11:44 am UTC

Tom,
I set up your JavaMail API from your book and when I execute I receive the following error:

ERROR at line 1:
ORA-29531: no method send in class mail
ORA-06512: at "SYS.SEND", line 0
ORA-06512: at line 6

Any thoughts on this?

Thanks!

Randy, August 19, 2004 - 12:12 pm UTC

Disregard last question, works great! Changed BLOB to BFILE in java source mail and problem was solved.

Randy, August 20, 2004 - 10:57 am UTC

Tom,
Any idea why the javamail API adds an extra space to my attachments? The spacing is not an issue when I view the files on the server. Attachments are sent from BFILEs. I wonder if anyone else has encountered similar problems.


Error sending email

A reader, August 24, 2004 - 11:23 am UTC

Hi Tom,

I have a procedure for sending emails, the code is provided below:

create or replace PROCEDURE send_mail
(p_sender IN VARCHAR2,
p_recipient IN VARCHAR2,
p_message IN VARCHAR2)
as
l_mailhost VARCHAR2(255) := 'smtp.1and1.com';
l_mail_conn utl_smtp.connection;
BEGIN
l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
utl_smtp.helo(l_mail_conn, l_mailhost);
utl_smtp.mail(l_mail_conn, p_sender);
utl_smtp.rcpt(l_mail_conn, p_recipient);
utl_smtp.open_data(l_mail_conn );
utl_smtp.write_data(l_mail_conn, p_message);
utl_smtp.close_data(l_mail_conn );
utl_smtp.quit(l_mail_conn);
end;
/

When I execute this procedure, I am getting ora-29278. pls help.

begin
send_mail(this@there.com', 'this1@there.com', 'Test email');
end;
/

ERROR at line 1:
ORA-29278: SMTP transient error: 421 Service not available
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 138

Thanks.

Tom Kyte
August 24, 2004 - 11:44 am UTC

421 Service not available

that is an SMTP error.

use the same approach documented above with telnet to reproduce without utl_smtp at all.

Followup using telnet

A reader, August 24, 2004 - 11:55 am UTC

Hi Tom,

As per your suggestion, I used telnet to try the SMTP connection. This is what happened. I did the following:

C:\>telnet smtp.1and1.com 25

The response was
Connecting to smtp.1and1.com...
220 Welcome to Nemesis ESMTP server on mrelay

and then it is just waiting at this point and I was not able to type anything after this.

pls help.

Thanks.

Tom Kyte
August 24, 2004 - 1:07 pm UTC

sounds like an SMTP problem -- it should just work, always does for me, if it does not, not much i can do from the database side.

send email

a reader, August 30, 2004 - 4:39 am UTC

SQL> create sequence sm_seq;

Sequence created.

SQL> create or replace procedure sm(p_to in varchar2,
  2   p_from in varchar2,
  3   p_subject in varchar2,
  4   p_body in varchar2)
  5  is
  6   l_output utl_file.file_type;
  7   l_filename varchar2(255);
  8   l_request varchar2(2000);
  9  begin
 10   select 'm' || sm_seq.nextval ||'.EMAIL.'||p_to
 11   into l_filename
 12   from dual;
 13   l_output :=utl_file.fopen('/tmp',l_filename,'w',32000);
 14   utl_file.put_line(l_output,'From: '||p_from);
 15   utl_file.put_line(l_output,'Subject: '||p_subject);
 16   utl_file.new_line(l_output);
 17   utl_file.put_line(l_output,p_body);
 18   utl_file.new_line(l_output);
 19   utl_file.put_line(l_output,'.');
 20   utl_file.fclose(l_output);
 21   l_request :=utl_http.request('
http://192.168.5.1/cgi-bin/smail?'
|| l_filename);
 22   dbms_output.put_line(l_request);
 23  end sm;
 24  /

Procedure created.

SQL> begin
  2  sm('asktom_us@oracle.com','asktom_us@oracle.com','Testing','hello world');
  3  end;
  4  /
begin
*
ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYS.UTL_FILE", line 98
ORA-06512: at "SYS.UTL_FILE", line 192
ORA-06512: at "SYSTEM.SM", line 13
ORA-06512: at line 2

Whould u please give me a good suggestion 

Tom Kyte
August 30, 2004 - 8:43 am UTC

maybe setup utl_file so that it can work?

SQL> show parameter utl_file_dir

odds are /tmp is not in it. 

sending email,loadjava

a reader, August 30, 2004 - 7:03 am UTC

I have downloaded required file like activation.jar and mail.jar.I followed ur way though it should be more easier.

1. Used WinZip to extract the contents of mail.jar into my c:\temp\mail
directory
2. Used WinZip to create a new archive c:\temp\mail8i.zip
3. Put the contents of c:\temp\mail\*.* including subdirectories into this new
archive

but how and where i use the following process

loadjava -u sys/manager -o -r -v -f -noverify -synonym -g public mail8i.zip
loadjava -u sys/manager -o -r -v -f -noverify -synonym -g public
activation8i.zip

would u please inform me


Tom Kyte
August 30, 2004 - 8:53 am UTC

command line.

send email

a reader, August 31, 2004 - 1:10 am UTC

you said and sql output
SQL> show parameter utl_file_dir;
NAME                                 TYPE    VALUE
------------------------------------ ------- 
utl_file_dir                         string
code i have previously written and error is same
ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "SYS.UTL_FILE", line 98
ORA-06512: at "SYS.UTL_FILE", line 192
ORA-06512: at "VIS.SM", line 13
ORA-06512: at line 2

SQL> loadjava -u sys/manager -o -r -v -f -noverify -synonym -g public activation8i.zip;
SP2-0734: unknown command beginning "loadjava -..." - rest of line ignored.
Please Please inform me 

Tom Kyte
August 31, 2004 - 8:52 am UTC

see, your utl_file_dir *is not set* -- fix that.

loadjava is a command line command,

$ loadjava .....

not a sqlplus command.

sending mail

a reader, September 01, 2004 - 6:16 am UTC

How can i fix it up

UTL_FILE/smtp

even from ur book expert one-on-one.

I tried to load loadjava.but huge errore.i don't know.how to fix it up.

</code> http://www.oracle.com/technology/sample_code/tech/pl_sql/htdocs/Utl_Smtp_Sample.html <code>

error in demo_mail package body

Line # = 138 Column # = 14 Error Text = PLS-00302: component 'WRITE_RAW_DATA' must be declared
Line # = 138 Column # = 5 Error Text = PL/SQL: Statement ignored
Line # = 145 Column # = 14 Error Text = PLS-00302: component 'WRITE_RAW_DATA' must be declared
Line # = 145 Column # = 5 Error Text = PL/SQL: Statement ignored

my version is
Oracle8i Enterprise Edition Release 8.1.6.0.0 - Production

would u please inform me precisely and elaborately
please..........

Tom Kyte
September 01, 2004 - 8:35 am UTC

precisely and elaborately... hmmm

anyway

SQL> desc utl_smtp


does your release have write_raw_data or not. 

Sending e-mail to multple recipients

Muneer Raza, September 01, 2004 - 10:20 am UTC

I am using Tom'example to send e-mail to multiple recipients. It works fine if I hard code the e-mail address
p_to => mail_pkg.array( 'mraza@beckman.com','rramanan@beckman.com' ).
But If I pass the more than one recipient e-mail address it fails with the following error message.

Cause: FDPSTP failed due to ORA-29279: SMTP permanent error: 501 Syntax error, parameters in command "RCPT TO:'mraza@beckman.com','rramanan@beckman.com'" unrecognized or missing
ORA-06512: at "SYS.UTL_SMTP", l

I also tried the following, but no luck, got the same error
l_user := '''mraza@beckman.com''' || ',' || '''rramanan@beckman.com''';
p_to => mail_pkg.array(l_user),



Tom Kyte
September 01, 2004 - 10:52 am UTC

if that is how you are passing multiple recipients, it is no wonder it fails.

you just send an email to the SINGLE user

'x@y.z,'r@a.b'

when you probably meant to send an email to two individuals.


soooo, put the recipients INTO AN ARRAY

l_user.extend;
l_user(l_user.count) := l_user1;
l_user.extend;
l_user(l_user.count) := l_user2;
.....

Error on java source

Matt Larson, September 03, 2004 - 4:07 pm UTC

I copied the code you had for creating java source above but I could not get it to work. I am getting the following error when I try to create the java source "mail"

create or replace and compile java source named "mail"
*
ERROR at line 1:
ORA-29536: badly formed source: Encountered "length" at line 34, column 23.
Was expecting one of:
"instanceof" ...
")" ...
">" ...
"<" ...
"?" ...
"==" ...
"<=" ...
">=" ...
"!=" ...
"||" ...
"&&" ...
"++" ...
"--" ...
"+" ...
"-" ...
"*" ...
"/" ...
"&" ...
"|" ...
"^" ...
"%" ...
"<<" ...
">>" ...
">>>" ...
"." ...
"[" ...
"(" ...




Tom Kyte
September 03, 2004 - 6:16 pm UTC

SQL> set define off


otherwise & has "meaning" to sqlplus and mucks up the code. 

sending mail

a reader, September 08, 2004 - 12:38 am UTC

SQL>desc utl_smtp
but nothing about write_raw_data
what should i do?

i am using broadband connection. 

Tom Kyte
September 08, 2004 - 9:19 am UTC

what does your connection type have to do with the version of Oracle you are using?

if you don't have write_raw_data, you won't be using that API, you need "more current software".

This package is great

Stan, November 16, 2004 - 2:44 pm UTC

But I have a question of using it.
When I populate variable with multiple recipients I get an error 20002: 501. Example: to_v := 'sss@sss.com, ttt@ttt.com, ooo@ooo.com';
When I use single e-mail there is no probles.

Please help.


Tom Kyte
November 16, 2004 - 11:06 pm UTC

not sure which one you are referring to.

the really simply one, doesn't deal with parsing a comma delimited list.

the other one takes an ARRAY (eg: neither parses a comma delimited list of names to email to...)

e-mail and attachment (oracle version 9.2.)

a reader, December 02, 2004 - 1:56 am UTC

Tom,

I will run a report and save the output as a csv file. Then I need to send this file as an attachment. How can I achieve this?

Thanks

Sending e-mail! -- Oracle 8i specific response

A reader, December 07, 2004 - 2:12 pm UTC

Followed your notes to setup the Loading and using the JavaMail API. The OS is HP-UX B.11.23 and DB is Oracle 9.2.0.5

When running the following command I got the following error:
loadjava -u sys/sonysys1 -o -r -v -f -noverify -synonym -g public mail9i.zip

The following operations failed
class com/sun/mail/imap/protocol/IMAPSaslAuthenticator$1: resolution
class com/sun/mail/imap/protocol/IMAPSaslAuthenticator: resolution
exiting : Failures occurred during processing


Problem with charset in JAVAMAIL

Violeta, December 10, 2004 - 5:04 pm UTC

Hi, Tom,
Thank you, this article was very usefull for me! But I have problems with JAVAMAIL.

I use character set "BLT8MSWIN1257" and when I send mail with attachment, body of recieved mail is OK, but I can not read attached text file.

I had to use attachmentData in CLOB, so I've modified your code, so this is my code:

"public static oracle.sql.NUMBER
send(String from,
String to,
String cc,
String bcc,
String subject,
String body,
String SMTPHost,
oracle.sql.CLOB attachmentData,
String attachmentType,
String attachmentFileName)
"


I replaced "oracle.sql.BLOB" to "oracle.sql.CLOB".
I added additional class:




" static class CLOBDataSource implements DataSource
{
private oracle.sql.CLOB data;
private String type;

CLOBDataSource(oracle.sql.CLOB data, String type)
{
this.type = type;
this.data = data;
}

public InputStream getInputStream() throws IOException
{
try
{
if(data == null)
throw new IOException("No data.");

/* return data.getAsciiStream();*/
return data.getCharacterStream();

} catch(SQLException e)
{
throw new
IOException("Cannot get input stream from CLOB.");
}
}

public OutputStream getOutputStream() throws IOException
{
throw new IOException("Cannot do this.");
}

public String getContentType()
{
return type;
}

public String getName()
{
return "CLOBDataSource";
}
}
"
Then I replaced "BLOBDataSource" with "CLOBDataSource",
but attached text file is undecipherable. What Did I wrong?

Thank You very much.

Tom Kyte
December 10, 2004 - 8:13 pm UTC

email doesn't understand "non standard charactersets" (well, it may well, but I'm no smtp expert)

basically -- things like that would need be base64 encoded (7bit ascii data) to be transmitted.

Table rows contents into mail body section

Tanweer, December 11, 2004 - 3:24 am UTC

Hi,
I want to send Table rows into the email BODY section

Can you guide me to take "emp" table contents

Thanks


Tom Kyte
December 11, 2004 - 7:57 am UTC

just build a string that represents your email body, nothing fancy or special.

Email of SQL query output (i.e Table’s rows contents with columns name for e.g dept)

Tanweer, December 13, 2004 - 6:51 am UTC

Hi,

I am using following code where I put the SQL output Can you guide me Please


CREATE OR REPLACE PROCEDURE SEND_MAIL_TCP (
msg_from VARCHAR2 := 'sender@testing.com'
, msg_to VARCHAR
, msg_subject VARCHAR2 := 'E-Mail message from your database'
, msg_text VARCHAR2 := ''
)
IS
c UTL_TCP.CONNECTION;
rc INTEGER;
BEGIN
c := UTL_TCP.OPEN_CONNECTION('localhost', 25); -- open the SMTP port 25 on local machine
rc := UTL_TCP.WRITE_LINE(c, 'HELO localhost');
rc := UTL_TCP.WRITE_LINE(c, 'MAIL FROM: '||msg_from);
rc := UTL_TCP.WRITE_LINE(c, 'RCPT TO: '||msg_to);
rc := UTL_TCP.WRITE_LINE(c, 'DATA'); -- Start message body
rc := UTL_TCP.WRITE_LINE(c, 'Subject: '||msg_subject);
rc := UTL_TCP.WRITE_LINE(c, '');
rc := UTL_TCP.WRITE_LINE(c, msg_text);
rc := UTL_TCP.WRITE_LINE(c, '.'); -- End of message body
rc := UTL_TCP.WRITE_LINE(c, 'QUIT');
UTL_TCP.CLOSE_CONNECTION(c); -- Close the connection
EXCEPTION
WHEN others THEN
RAISE_APPLICATION_ERROR(-20000, 'Unable to send e-mail message from PL/SQL routine.');
END;

Thanks


Tom Kyte
December 13, 2004 - 10:19 am UTC

rc := UTL_TCP.WRITE_LINE(c, msg_text);

put your sql output there..

Email of SQL query output (i.e Table’s rows contents with columns name for e.g dept)

tanweer, December 14, 2004 - 6:58 am UTC

Hi,

I have putted the SQL Query "Select * from dept;" in place of "msg_text"

OR even pass into the parameter of procedure "SEND_MAIL_TCP "

But the result doesnot display into the mail body section

Thanks in Adv

Tom Kyte
December 14, 2004 - 9:05 am UTC

of course not. you have to run the query, get the data, format the data, output the data.

FYI for UTL_SMTP if via Web Form

Meyer, December 14, 2004 - 1:35 pm UTC

This is an FYI for those using UTIL_SMTP as a building block in their apps....

I just found this out today (after one of my app's had been in production for years working fine)...new problem, debugged it and thought this could save others some steps as I first looked at the network, firewall, relay settings based on googling the error mesg.

As a part of SMTP, a period "." on its own line in the data/body (SMTP DATA COMMAND) tells SMTP the body text is done....(CRLF.CRLF)

If a person fills out a form on your site...and that form text becomes emailed text....and if that person put a period alone on its own line in that form they wrote...it causes an SMTP error (all text following the "command" in the email body becomes invalid SMTP commands).

The solution I found was add a space after any periods that are followed by a newline in the text before I give to SMTP....(space between the perod and the newline)...it looks the same in the email but it not the CRLF.CRLF command

replace(
THE_BODY_BLOB,
'.'||chr(13),
'. '||chr(13)
);

This takes place on all the periods in the body...but only "Fixes" it if the period starts the new line.

Hope this helps.

Thanks,
Meyer

A reader, December 14, 2004 - 3:54 pm UTC

I have a same requirement as this one, sending emails from my stored procedure.
I am trying to use the package you suggested here,
Util_SMTP.Open_Conection ( host IN VARCHAR2,
port IN PLS_INTEGER DEFAULT 25,
c OUT connection,
tx_timeout IN PLS_INTEGER DEFAULT NULL)
What is the value of host is this case?
I am trying to send email to my personal account.
Thanks!



Tom Kyte
December 15, 2004 - 1:02 pm UTC

your SMTP server hostname

Email of SQL query output (i.e Table’s rows contents with columns name for e.g dept)

tanweer, December 15, 2004 - 1:27 am UTC

Hi,

Can you give the detail IDEA how the any Query Data send into the email BOdy section.

suppose my Query is that : SQL > Select Deptno, dname from dept ;

Thank you in Advance

Tom Kyte
December 15, 2004 - 1:29 pm UTC

for x in (select * from emp)
loop
UTL_TCP.WRITE_LINE(c, x.ename || ', ' || x.empno );
end loop;




Email of SQL query output (i.e Table’s rows contents with columns name for e.g emp)

Tanweer, December 16, 2004 - 6:24 am UTC

Hi,
Thanks for your assistance,
I used ur code but I am not able to receive any mail
please can you check it

CREATE OR REPLACE PROCEDURE SEND_MAIL_TCP (
msg_from VARCHAR2 := 'tanweer_q@yahoo.com' ---'sender@testing.com'
, msg_to VARCHAR
, msg_subject VARCHAR2 := 'E-Mail message from your database'
, msg_text VARCHAR2 := ''
)
IS
c UTL_TCP.CONNECTION;
rc INTEGER;
BEGIN
c := UTL_TCP.OPEN_CONNECTION('localhost', 25); -- open the SMTP port 25 on local machine
rc := UTL_TCP.WRITE_LINE(c, 'HELO localhost');
rc := UTL_TCP.WRITE_LINE(c, 'MAIL FROM: '||msg_from);
rc := UTL_TCP.WRITE_LINE(c, 'RCPT TO: '||msg_to);
rc := UTL_TCP.WRITE_LINE(c, 'DATA'); -- Start message body
rc := UTL_TCP.WRITE_LINE(c, 'Subject: '||msg_subject);
rc := UTL_TCP.WRITE_LINE(c, '');
rc := UTL_TCP.WRITE_LINE(c, msg_text);
for x in (select * from emp)
loop
rc := UTL_TCP.WRITE_LINE(c, x.ename || ', ' || x.empno );
end loop;
rc := UTL_TCP.WRITE_LINE(c, '.'); -- End of message body
rc := UTL_TCP.WRITE_LINE(c, 'QUIT');
UTL_TCP.CLOSE_CONNECTION(c); -- Close the connection
EXCEPTION
WHEN others THEN
RAISE_APPLICATION_ERROR(-20000, 'Unable to send e-mail message from PL/SQL routine.');
END;

EXEC SEND_MAIL_TCP ( msg_to => 'tanweer_q@rediffmail.com', msg_text => 'This is a test message.');

Regd Tanweer


Tom Kyte
December 16, 2004 - 8:46 am UTC

worked for me.

It is highly unlikely your smtp server is actually running on localhost however. And if it were, it is really unlikely others would allow it to relay through them.


This has nothing to do with Oracle right now, you need to find out what your smtp server configuration on your site really is (eg: go into your email client and see what smtp server your email client is configured to use)

A reader, December 16, 2004 - 11:24 am UTC

Tanveer,

It is not working for me too. What TOm says should be true as, the same thing was wroking at my earlier clients place.
I am not able to figure out how to fix this though...

Let me know if you find something!

Thanks!

following operations failed

Yiming, December 21, 2004 - 4:01 pm UTC

Hi, Tom
When I follows your step to loadjava, first activation8i, then mail8i I got the message at last:

.....
The following operations failed
source msgshow: resolution
source smtpsend: resolution
exiting : Failures occurred during processing

Then I try to create or replace and compile
java source named "mail" at a user account I got:

Enter value for to:
old 37: if (to != null && to.length() > 0)
new 37: if (to != null length() > 0)
Enter value for cc:
old 40: if (cc != null && cc.length() > 0)
new 40: if (cc != null length() > 0)
Enter value for bcc:
old 43: if (bcc != null && bcc.length() > 0)
new 43: if (bcc != null length() > 0)
Enter value for subject:
old 46: if ( subject != null && subject.length() > 0 )
new 46: if ( subject != null length() > 0 )
java source named "mail"
*
ERROR at line 2:
ORA-29536: badly formed source: Encountered "length" at line 34, column 23.

Was expecting one of:

"instanceof" ...

")" ...

">" ...

"<" ...

"?" ...

"==" ...

"<=" ...

">=" ...

"!=" ...

"||" ...

"&&" ...

"++" ...

"--" ...

"+" ...

"-" ...

"*" ...

"/" ...

"&" ...

"|" ...

"^" ...

"%" ...

"<<" ...

">>" ...

">>>" ...

"." ...

"[" ...

"(" ...

Could you tell me what's wrong. My database version is 9iR2. Thanks


Tom Kyte
December 21, 2004 - 7:08 pm UTC

SQL> set define OFF


 

following operations failed

yiming, December 21, 2004 - 5:42 pm UTC

Hi, Tom,
The problem has been solved. I download javamail1.3 version instead of new 1.3.2 and follow your step reload java again. At last no any message showed up.

.....
skipping : resource javamail-1.3/mail.jar
granting : execute on resource javamail-1.3/NOTES.txt to public
skipping : resource javamail-1.3/NOTES.txt
granting : execute on resource javamail-1.3/README.txt to public
skipping : resource javamail-1.3/README.txt
verifier : on

But when I create or replace and compile
java source named "mail" at scott there are error msg like:
scott@TEST1> show errors
Errors for JAVA SOURCE mail:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 mail:83: Interface DataSource of nested class mail.
BLOBDataSource not found.

0/0 mail:31: Class Message not found.
0/0 mail:32: Class MimeMessage not found.
0/0 mail:38: Variable msg may not have been initialized.
0/0 mail:41: Variable msg may not have been initialized.
0/0 mail:44: Variable msg may not have been initialized.
0/0 mail:45: Variable msg may not have been initialized.
0/0 mail:46: Variable msg may not have been initialized.
0/0 mail:49: Class MimeBodyPart not found.

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 mail:49: Class MimeBodyPart not found.
0/0 mail:52: Class MimeBodyPart not found.
0/0 mail:52: Class MimeBodyPart not found.
0/0 mail:62: Class MimeMultipart not found.
0/0 mail:62: Class MimeMultipart not found.
0/0 mail:71: Undefined variable or class name: Transport
0/0 Info: 15 errors

when I connect sys then "Java created."

You gave us so many very useful tips. Thank you very much.


Error in email

tanweer, December 22, 2004 - 1:44 am UTC

SQL> DECLARE
  2    l_mailhost    VARCHAR2(64) := 'abctrad.com'; --'mail.mycompany.com';
  3    l_from        VARCHAR2(64) := 'tanweer_q@yahoo.com';--'me@mycompany.com';
  4    l_subject     VARCHAR2(64) := 'Test Mail';
  5    l_to          VARCHAR2(64) := 'tanweer_q@rediffmail.com';--'you@mycompany.com';
  6    l_mail_conn   UTL_SMTP.connection;
  7  BEGIN
  8    l_mail_conn := UTL_SMTP.open_connection(l_mailhost, 25);
  9    UTL_SMTP.helo(l_mail_conn, l_mailhost);
 10    UTL_SMTP.mail(l_mail_conn, l_from);
 11    UTL_SMTP.rcpt(l_mail_conn, l_to);
 12  
 13    UTL_SMTP.open_data(l_mail_conn);
 14    
 15    UTL_SMTP.write_data(l_mail_conn, 'Date: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || Ch
r(13));
 16    UTL_SMTP.write_data(l_mail_conn, 'From: ' || l_from || Chr(13));
 17    UTL_SMTP.write_data(l_mail_conn, 'Subject: ' || l_subject || Chr(13));
 18    UTL_SMTP.write_data(l_mail_conn, 'To: ' || l_to || Chr(13));
 19    UTL_SMTP.write_data(l_mail_conn, '' || Chr(13));
 20    
 21    FOR i IN 1 .. 10 LOOP
 22      UTL_SMTP.write_data(l_mail_conn, 'This is a test message. Line ' 
 23      || To_Char(i) || Chr(13));
 24    END LOOP;
 25    
 26    UTL_SMTP.close_data(l_mail_conn);
 27  
 28    UTL_SMTP.quit(l_mail_conn);
 29  END;
 30  /
DECLARE
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 8
ORA-29278: SMTP transient error: 451 4.3.0 Data command failed.
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 317
ORA-06512: at line 26
 

Tom Kyte
December 22, 2004 - 8:54 am UTC

ops$tkyte@ORA9IR2> DECLARE
  2    l_mailhost       VARCHAR2(64) := 'xxxx.com'; --'mail.mycompany.com';
  3    l_from        VARCHAR2(64) := 'tom@yahoo.com';--'me@mycompany.com';
  4    l_subject        VARCHAR2(64) := 'Test Mail';
  5    l_to          VARCHAR2(64) := 'tkyte@oracle.com';--'you@mycompany.com';
  6    l_mail_conn      UTL_SMTP.connection;
  7  BEGIN
  8    l_mail_conn := UTL_SMTP.open_connection(l_mailhost, 25);
  9    UTL_SMTP.helo(l_mail_conn, l_mailhost);
 10    UTL_SMTP.mail(l_mail_conn, l_from);
 11    UTL_SMTP.rcpt(l_mail_conn, l_to);
 12
 13    UTL_SMTP.open_data(l_mail_conn);
 14
 15    UTL_SMTP.write_data(l_mail_conn, 'Date: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS') || Chr(13));
 16    UTL_SMTP.write_data(l_mail_conn, 'From: ' || l_from || Chr(13));
 17    UTL_SMTP.write_data(l_mail_conn, 'Subject: ' || l_subject || Chr(13));
 18    UTL_SMTP.write_data(l_mail_conn, 'To: ' || l_to || Chr(13));
 19    UTL_SMTP.write_data(l_mail_conn, '' || Chr(13));
 20
 21    FOR i IN 1 .. 10 LOOP
 22      UTL_SMTP.write_data(l_mail_conn, 'This is a test message. Line '
 23      || To_Char(i) || Chr(13));
 24    END LOOP;
 25
 26    UTL_SMTP.close_data(l_mail_conn);
 27
 28    UTL_SMTP.quit(l_mail_conn);
 29  END;
 30  /
 
PL/SQL procedure successfully completed.


I cannot reproduce and have never seen that.

the only remotely similar thing I see is with shared server connections (it is similar only).  Are you using shared server, does it reproduce when you use a dedicated server. 

Just to share.........

Sikandar Hayat Awan, December 29, 2004 - 10:30 pm UTC

Hi,
I found a bug ralted to utl_mail in 10g posted on metalink so thought to share it with all of.

Hi,
Installed utl_mail package, set the smtp_out_server parameter in the init.ora and tried sending mail using the following example.

begin
utl_mail.send(sender=>'testd',recipients=>'satish.iyer@abc.com,subject=>'test message',message=>'Text message only',
mime_type=>'text/html');
end;

I am receiving the mail okay, however the sender, recepient and the subject in the mail are preceeded by the database character set.
Like this...
"=?US7ASCII?Q?testd?=@lgis2000.abc.com"

--- Oracle Response ----
This is due to bug 3506588 which is fixed in upcoming release of Oracle 10G. Currently backports for this bug do not exist.

--------URL----------

</code> http://metalink.oracle.com/metalink/plsql/ml2_gui.startup <code>

Sending to many one by one using utl_smtp

Purrah, January 13, 2005 - 6:06 am UTC

Hi Tom
The solution you wrote 2/3 years ago was very helpful
but I have a a problem when sending to many recipients. I call the send procedure and pass some arguments which are different addresses then at some stage it will give me the ff errors.
ORA-20001: 421 Server too busy
and then after that it will give....
ORA-20001: 421 Service not available
Is there a way of keeping the UTL_SMTP working and ready to receive more requests..

Regard and Thanks for the Good work you doing



Tom Kyte
January 13, 2005 - 9:00 am UTC

ask your system admins, this is a problem with your smtp server itself -- nothing in the database.

UTL_MAIL

a reader, February 02, 2005 - 5:23 pm UTC

Hi Tom,

I have been looking into sending attachments using Oracle 10g. Could you explain me the following lines, in context with the operational notes given below.

"However, if SMTP_OUT_SERVER is not defined, this invokes a default of DB_DOMAIN which is guaranteed to be defined to perform appropriately."

Operational Notes
You must both install UTL_MAIL and define the SMTP_OUT_SERVER.

To install UTL_MAIL: 
sqlplus sys/<pwd>
SQL> @$ORACLE_HOME/rdbms/admin/utlmail.sql
SQL> @$ORACLE_HOME/rdbms/admin/prvtmail.sql


You define the SMTP_OUT_SERVER parameter in the init.ora rdbms initialization file. However, if SMTP_OUT_SERVER is not defined, this invokes a default of DB_DOMAIN which is guaranteed to be defined to perform appropriately.

Thanks in advance, 

Tom Kyte
February 03, 2005 - 1:37 am UTC

it is saying "if you don't set the smtp out server, we'll use what we find in the db_domain parameter - and that is probably not your smtp server so set the smtp out server parameter so mail can actually be sent"



possible workaround for empty mail messages.

G.J. Ruiter, February 03, 2005 - 8:52 am UTC

Subject: possible workaround for empty messages.

Hello Tom,
Two people mentioned that they got an empty message(
May 13, 2003 and July 29, 2004)

I had the same problem, but here everything after a blank line was sent.
message:='line1'||crlf||crlf||'line2'||crlf||'line3';
and I received:
------------

line2

line3
------------
This also happened when I tested using Telnet, only data after a blank line was sent.
We use Microsoft Exchange Internet Mail Service 5.5.2657.72), the problem does not occur when I send mail to other accounts which probably use other mail servers.

Also; here everything works when I start my message with a blank line.

Yours sincerely,

G.J. Ruiter.


Email Validation

Ray DeBruyn, February 03, 2005 - 12:38 pm UTC

Using utl_smtp, you make a connection to the email server and essentially run commands. The utl_smtp package has a function to validate the email, the problems are that you need permission on the email server to run the command and the task requires connecting to the remote server to validate the email. If you wish validate 100 emails, it could be time consuming, but it could be used to validate an individual email as it is inserted or updated.
Validating against the email client assumes that this email is in your address book.

Still having problems with loadjava

Jean C., February 17, 2005 - 10:34 am UTC

Hi Tom
I'm having this situation in my test DB:

$ loadjava -user sys/xxxxxxx plsql.jar
Error while creating resource META-INF/MANIFEST.MF
ORA-03113: end-of-file on communication channel

loadjava: 1 errors

When I check the trace file, this is what I get:
/var/log/oracle/dnod/users/ora_20803.trc
Oracle8i Enterprise Edition Release 8.1.7.4.0 - Production
JServer Release 8.1.7.4.0 - Production
ORACLE_HOME = /opt/oracle/8.1.7
System name: Linux
Node name: dexter1
Release: 2.4.27
Version: #1 Mon Oct 18 09:49:41 VET 2004
Machine: i686
Instance name: DNOD
Redo thread mounted by this instance: 1
Oracle process number: 12
Unix process pid: 20803, image: oracle@dexter1 (TNS V1-V3)

*** SESSION ID:(18.18176) 2005-02-17 11:16:19.674
Exception signal: 11 (SIGSEGV)
*** 2005-02-17 11:16:19.703
ksedmp: internal or fatal error
Current SQL statement for this session:
create or replace java resource named "META-INF/MANIFEST.MF" using 'META-INF/MANIFEST.MF'
----- Call Stack Trace -----
calling call entry argument values in hex
location type point (? means dubious value)
-------------------- -------- -------------------- ----------------------------
Cannot seek to string table section header in /lib/libdl.so.2.
Exception signal: 11 (SIGSEGV)
*** 2005-02-17 11:16:19.767
ksedmp: internal or fatal error
Current SQL statement for this session:
create or replace java resource named "META-INF/MANIFEST.MF" using 'META-INF/MANIFEST.MF'
----- Call Stack Trace -----
calling call entry argument values in hex
location type point (? means dubious value)
-------------------- -------- -------------------- ----------------------------
Cannot seek to string table section header in /lib/libdl.so.2.
Exception signal: 11 (SIGSEGV)
*** 2005-02-17 11:16:19.831
ksedmp: internal or fatal error
Current SQL statement for this session:
create or replace java resource named "META-INF/MANIFEST.MF" using 'META-INF/MANIFEST.MF'
----- Call Stack Trace -----
calling call entry argument values in hex
location type point (? means dubious value)
-------------------- -------- -------------------- ----------------------------
Cannot seek to string table section header in /lib/libdl.so.2.
Shadow_Core_Dump = PARTIAL

I'm stucked here.
Thanks in advanced

Tom Kyte
February 17, 2005 - 1:42 pm UTC

3113, 7445, 600 -> call support please.

sometime getting error ORA-29279

Sikandar Hayat Awan, April 12, 2005 - 5:52 am UTC


I have configured automatic emailing with job scheduling and everything is working fine. But few job are failing with the following error,

ORA-12012: error on auto execute of job 4211
ORA-29279: SMTP permanent error: 501 5.5.4 Invalid Address
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 98
ORA-06512: at "SYS.UTL_SMTP", line 240
ORA-06512: at "SYSTEM.SKR_EMAIL_HTML", line 20
ORA-06512: at "CPO.IGP_EMAIL", line 128
ORA-06512: at line 1

The percentage of such is 5 out of 100 so trying to figure it out why these jobs are failing.

Thanks in advance for your time and cooperation.

Tom Kyte
April 12, 2005 - 7:28 am UTC

</code> http://www.greenend.org.uk/rjk/2000/05/21/smtp-replies.html <code>

your request (inputs) to smtp were invalid.

add exception handler, log inputs so you can test it in sqlplus -- you'll probably see what was wrong just looking at it.

A reader, April 18, 2005 - 1:02 pm UTC

I am using 9.2.0.5 Database on Sun Solaris.

10g?

whizkid, April 30, 2005 - 6:15 am UTC

Will this work in 10g as well? We have recently upgraded our database 10.1.0.4 (RH Linux ES 3). JavaMail was working beautifully for our 9i database but after the upgrade, I loaded activation & sendmail into the database 

PROCEDURE Send_Mail_Attach(DataPeriod VARCHAR)
AS
      ret_code NUMBER;
    BEGIN
      FOR i IN (SELECT * FROM DAILY_FILE_STORE WHERE TRUNC(FILE_DATE) = TRUNC(SYSDATE) AND file_name LIKE 'KFL%')
      LOOP
        ret_code := Send(
                     p_from => 'xxx@xxx.com',
                     p_to => 'xxx@xxx.com',
                     p_cc => 'xxx@xxx.com',
                     p_bcc => NULL,
                     p_subject => 'Data for ' || DataPeriod,
                     p_body => 'Dear User, Please find attached the upload data for the period mentioned in the subject line.',
                     p_smtp_host => '172.28.70.44',
                     p_attachment_data => i.FILE_DUMP,
                     p_attachment_type => 'application/ms-excel',
                     p_attachment_file_name => i.FILE_NAME);
       IF ret_code = 1 THEN
         dbms_output.put_line ('Successfully sent message...');
       ELSE
         dbms_output.put_line ('Failed to send message...');
       END IF;
     END LOOP;
   END;

SQL> set serverout on
SQL> exec send_mail_attach('KFL29APR2005')
Failed to send message...

PL/SQL procedure successfully completed.

There's a utl_mail procedure in 10g which does this but I think there's a limitation on the size of the attachment.

CREATE OR REPLACE PROCEDURE Mail_Attach (dir1 VARCHAR2, filename VARCHAR2)
AS
     l_output   utl_file.file_type;
     l_file          RAW(32767);
     l_size          NUMBER;
     BLOCK           NUMBER;
     b               BOOLEAN;
     l_start NUMBER := 1;
     TYPE ARRAY IS TABLE OF VARCHAR2(255);
     l_data ARRAY := ARRAY('xx@indiainfo.com','xx@email.com','xx@yahoo.co.in','xx@bajajallianz.co.in' );
   BEGIN
     UTL_FILE.FGETATTR(dir1, filename, b, l_size, BLOCK);
     l_output := utl_file.fopen(dir1, filename, 'r' );
     utl_file.get_raw(l_output, l_file, l_size);
     utl_file.fclose( l_output );
     FOR i IN l_start .. l_data.COUNT
     LOOP
         UTL_MAIL.SEND_ATTACH_RAW (
               sender     => 'Bagic@Mailer',
               recipients => l_data(i),
               subject    => 'KFL Data for ' || TO_CHAR((SYSDATE-1),'DD-MON-YYYY'),
               attachment => l_file,
               message    => 'Dear User, Please find attached the upload data for the period mentioned in the subject line.',
               att_inline => FALSE,
               att_filename => filename);
               l_start := l_start + 1;
     END LOOP;
   END;
/


SQL> exec mail_attach('UTL_PATH','KFL29-APR-2005')
BEGIN mail_attach('UTL_PATH','KFL29-APR-2005'); END;

*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: raw variable length too long
ORA-06512: at "SYS.UTL_ENCODE", line 243
ORA-06512: at "SYS.UTL_MAIL", line 118
ORA-06512: at "SYS.UTL_MAIL", line 324
ORA-06512: at "SYS.UTL_MAIL", line 414
ORA-06512: at "PROD.MAIL_ATTACH", line 18
ORA-06512: at line 1

SQL> select directory_name, directory_path from dba_directories where directory_name like '%UTL%';

DIRECTORY_NAME                 DIRECTORY_PATH
------------------------------ ----------------------------------------
UTL_PATH                       /app/oracle/admin/DWH/utl

SQL> !ls -l /app/oracle/admin/DWH/utl
total 28
-rw-r--r--    1 oracle   oinstall    25360 Apr 30 15:26 KFL29-APR-2005

 

Tom Kyte
April 30, 2005 - 11:03 am UTC

utl_mail would be much much easier. I haven't bothered even trying in 10g


</code> http://docs.oracle.com/docs/cd/B14117_01/appdev.101/b10802/u_mail.htm#996728 <code>

I have tried utl_mail in 10g

whizkid, May 01, 2005 - 5:30 am UTC

and pasted the results of that above..

CREATE OR REPLACE PROCEDURE Mail_Attach (dir1 VARCHAR2, filename VARCHAR2)
AS
     l_output   utl_file.file_type;
     l_file          RAW(32767);
     l_size          NUMBER;
     BLOCK           NUMBER;
     b               BOOLEAN;
     l_start NUMBER := 1;
     TYPE ARRAY IS TABLE OF VARCHAR2(255);
     l_data ARRAY := 
ARRAY('xx@indiainfo.com','xx@email.com','xx@yahoo.co.in','xx@bajajallianz.co.in' 
);
   BEGIN
     UTL_FILE.FGETATTR(dir1, filename, b, l_size, BLOCK);
     l_output := utl_file.fopen(dir1, filename, 'r' );
     utl_file.get_raw(l_output, l_file, l_size);
     utl_file.fclose( l_output );
     FOR i IN l_start .. l_data.COUNT
     LOOP
         UTL_MAIL.SEND_ATTACH_RAW (
               sender     => 'Bagic@Mailer',
               recipients => l_data(i),
               subject    => 'KFL Data for ' || 
TO_CHAR((SYSDATE-1),'DD-MON-YYYY'),
               attachment => l_file,
               message    => 'Dear User, Please find attached the upload data 
for the period mentioned in the subject line.',
               att_inline => FALSE,
               att_filename => filename);
               l_start := l_start + 1;
     END LOOP;
   END;
/


SQL> exec mail_attach('UTL_PATH','KFL29-APR-2005')
BEGIN mail_attach('UTL_PATH','KFL29-APR-2005'); END;

*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: raw variable length too long
ORA-06512: at "SYS.UTL_ENCODE", line 243
ORA-06512: at "SYS.UTL_MAIL", line 118
ORA-06512: at "SYS.UTL_MAIL", line 324
ORA-06512: at "SYS.UTL_MAIL", line 414
ORA-06512: at "PROD.MAIL_ATTACH", line 18
ORA-06512: at line 1

SQL> select directory_name, directory_path from dba_directories where 
directory_name like '%UTL%';

DIRECTORY_NAME                 DIRECTORY_PATH
------------------------------ ----------------------------------------
UTL_PATH                       /app/oracle/admin/DWH/utl

SQL> !ls -l /app/oracle/admin/DWH/utl
total 28
-rw-r--r--    1 oracle   oinstall    25360 Apr 30 15:26 KFL29-APR-2005

Is there a restriction on the length of the attachment? I have searched your site and metalink but couldnt find anything... 

Tom Kyte
May 01, 2005 - 9:00 am UTC

I don't see all followups to every review -- and I tend not to re-read the page when I get new ones (so if there isn't any reference to something above, I don't really put them together...)


can you see support note

Note 269375.1

Note: 269375.1

whizkid, May 03, 2005 - 3:08 am UTC

Tom, that note is not accessible to me. It says your search returned no hits. Maybe its an internal document. Can you copy & paste the contents here? or can you email it to me?

Thanks a lot!

Tom Kyte
May 03, 2005 - 1:37 pm UTC

Looks like an issue -- can you work with this:

</code> http://www.oracle.com/technology/sample_code/tech/pl_sql/htdocs/Utl_Smtp_Sample.html <code>

for now, it seems to work well.

wher is problem (PLZ help me)

bhaskar, May 05, 2005 - 8:15 am UTC

package com.tattva.pms.servlet;
import java.io.*;
import java.util.*;
import javax.mail.*;
import javax.mail.event.*;
import javax.mail.internet.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.activation.*;
import com.tattva.pms.Mailing.*;

public class MailerS extends HttpServlet {

String to = "";
String cc = "";
String bcc = "";
String from = "";
String subject = "";
String message1 = "";

public void init(ServletConfig config) throws ServletException{
super.init(config);
System.out.println("star333333333");

}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

String [] str = null;

Properties props =null;
Session session = null;
props = System.getProperties();
props.put("mail.smtp.host","10.0.0.180");
session = Session.getDefaultInstance(props, null);

System.out.println("start44444444444");


HttpServletResponseWrapper responseWrapper = new HttpServletResponseWrapper(response);
PrintWriter out = response.getWriter();
response.setContentType("text/plain");

String[] recipients = request.getParameter("to");
cc = request.getParameter("cc");
bcc = request.getParameter("bcc");
from = request.getParameter("from");
subject = request.getParameter("subject");
message1= request.getParameter("message");
System.out.println("aaatotototo"+to);
System.out.println("bbfromfromfrom"+from);
System.out.println("cccsubjectsubject"+subject);
System.out.println("message"+message1);
System.out.println("the vale of From");

if(!(everythingIsSet())){

System.out.println("Could not send email.");
}

try {
System.out.println("start try block");
MimeMessage message2 = new MimeMessage(session);
// MimeMessage message = new MimeMessage(session);

// System.out.println("start if block");
System.out.println("the To value"+to);


if( (!(to.trim().equalsIgnoreCase(""))) && !(to==null) && (!(to.trim().equalsIgnoreCase("null"))) ){
System.out.println("In if block");

str =to.split(",");
System.out.println("for set message block");
//InternetAddress[] address = {new InternetAddress(to)};
// message2.setRecipients(Message.RecipientType.TO,address);




// Stringp[] recipients = {"one@test.com", "two@test.com"};

InternetAddress[] addressTo = new InternetAddress[recipients.length];
for (int i = 0; i < recipients.length; i++) {
addressTo = new InternetAddress(recipients);
}
message2.addRecipients(Message.RecipientType.TO, addressTo);
/* message.setRecipient(Message.RecipientType.TO,new InternetAddress(str[0], false));

for (int i=1; i< str.length;i++) {
System.out.println("the I value is"+i);
System.out.println("before send to message block");

message.addRecipient(Message.RecipientType.TO,new InternetAddress(str[i], false));
System.out.println("after send to message block");


}*/
}
System.out.println("In if block for cc");

System.out.println("the Cc value"+cc);

if( (!(cc.trim().equalsIgnoreCase(""))) && !(cc==null) && (!(cc.trim().equalsIgnoreCase("null"))) ){
System.out.println("In if block in cc condition");

str = cc.split(",");
System.out.println("for setmessage block for cc");
InternetAddress[] address = {new InternetAddress(cc)};
message2.setRecipients(Message.RecipientType.CC,address);

/*message.setRecipient(Message.RecipientType.CC,new InternetAddress(str[0], false));
for (int i=1; i< str.length;i++) {
System.out.println("before send to message block for cc");

message.addRecipient(Message.RecipientType.CC,new InternetAddress(str[i], false));
System.out.println("after send to message block CC");

}*/ System.out.println("sage block");

}
System.out.println("theBCc value"+bcc);

if( (!(bcc.trim().equalsIgnoreCase(""))) && !(bcc==null) && (!(bcc.trim().equalsIgnoreCase("null"))) ){
str = bcc.split(",");
/* message.setRecipient(Message.RecipientType.BCC,new InternetAddress(str[0], false));
for (int i=1; i< str.length;i++) {
message.addRecipient(Message.RecipientType.BCC,new InternetAddress(str[i],false));
}*/
InternetAddress[] address = {new InternetAddress(bcc)};
message2.setRecipients(Message.RecipientType.BCC,address);
System.out.println("theBCCCCCCCCC");

}
System.out.println("fromfromfromfromfrom1111111");

message2.setFrom(new InternetAddress(from));
System.out.println("fromfromfromfromfrom222222222222");
message2.setSubject(subject);
System.out.println("mmmmmmmmmmmmm"+message2);

message2.setText(message1);
System.out.println("11111111111ghjhhnbmbbjmbbhhbhbhn");

Transport.send(message2);
System.out.println("Totlatotltotltolto"+message2);


System.out.println("sucess");
}
catch (MessagingException e) {
System.out.println("mailer Exception"+e.getMessage());
}

}

boolean everythingIsSet() {
if((to == null) || (from == null) ||
(subject == null) || (message1 == null))
return false;

if((to.indexOf("@") == -1) ||
(to.indexOf(".") == -1))
return false;

if((from.indexOf("@") == -1) ||
(from.indexOf(".") == -1))
return false;

return true;
}
}

Tom Kyte
May 05, 2005 - 9:19 am UTC

looks like code? not sure what to say...

Multiple ORA-29521 errors.

Stacey Jones, May 06, 2005 - 2:12 pm UTC

When I issue the following statement:

loadjava -u system/test@tds_test -o -r -v -f -noverify -synonym -g public mail8i.zip

I get the following error stack...

skipping : class com/sun/mail/imap/protocol/IMAPProtocol
synonym : com/sun/mail/imap/protocol/IMAPProtocol
granting : execute on class com/sun/mail/imap/protocol/IMAPResponse to public
skipping : class com/sun/mail/imap/protocol/IMAPResponse
synonym : com/sun/mail/imap/protocol/IMAPResponse
granting : execute on class com/sun/mail/imap/protocol/IMAPSaslAuthenticator$1 to public
resolving: class com/sun/mail/imap/protocol/IMAPSaslAuthenticator$1
errors : class com/sun/mail/imap/protocol/IMAPSaslAuthenticator$1
ORA-29521: referenced name javax/security/auth/callback/NameCallback could not be found
ORA-29521: referenced name javax/security/auth/callback/PasswordCallback could not be found
ORA-29521: referenced name javax/security/sasl/RealmCallback could not be found
ORA-29521: referenced name javax/security/sasl/RealmChoiceCallback could not be found
ORA-29521: referenced name javax/security/auth/callback/CallbackHandler could not be found
ORA-29521: referenced name javax/security/auth/callback/Callback could not be found
synonym : com/sun/mail/imap/protocol/IMAPSaslAuthenticator$1
granting : execute on class com/sun/mail/imap/protocol/IMAPSaslAuthenticator to public
errors : class com/sun/mail/imap/protocol/IMAPSaslAuthenticator
ORA-29534: referenced object SYSTEM.com/sun/mail/imap/protocol/IMAPSaslAuthenticator$1 could not be resolved
ORA-29521: referenced name javax/security/sasl/SaslException could not be found
ORA-29521: referenced name javax/security/sasl/Sasl could not be found
ORA-29521: referenced name javax/security/sasl/SaslClient could not be found
ORA-29521: referenced name javax/security/auth/callback/CallbackHandler could not be found
synonym : com/sun/mail/imap/protocol/IMAPSaslAuthenticator
granting : execute on class com/sun/mail/imap/protocol/INTERNALDATE to public
skipping : class com/sun/mail/imap/protocol/INTERNALDATE
synonym : com/sun/mail/imap/protocol/INTERNALDATE

...I went to metalink and it suggested putting "<JDK_HOME>/lib" in the classpath but that didn't help. Any help you can give is much appreciated!



Tom Kyte
May 06, 2005 - 5:08 pm UTC

what version of the database.

How to email multiple attachments to multiple people with JavaMail API

Yai, May 09, 2005 - 5:37 pm UTC

Hi Tom,

I learned from your Expert one-on-one how to email to multiple people using utl_smtp. Now I want to email multiple attachments to multiple people. You suggested JavaMail API if attachments were involved, but how can I email multiple attachments to multiple people?

Thank you very much.

Tom Kyte
May 09, 2005 - 5:51 pm UTC

code is all here, you just need to modify it to suit your needs.

NoSuchProviderException

Stacey Jones, May 10, 2005 - 2:39 pm UTC

I resolved my previous exception. I was using a newer version of the mail class than you used. Downloaded the older version and got past that error but now when I run this test block:

declare
ret_code number;
begin
dbms_output.enable( 1000000 );
dbms_java.set_output( 1000000 );
commit;
ret_code := send(
p_from => 'rsjones@ups-scs.com',
p_to => 'rsjones@ups-scs.com',
p_cc => NULL,
p_bcc => NULL,
p_subject => 'Use the attached Zip file',
p_body => 'to send email with attachments....',
p_smtp_host => 'winsmtp.ups.com',
p_attachment_data => null,
p_attachment_type => null,
p_attachment_file_name => null);
if ret_code = 1 then
dbms_output.put_line ('Successfully sent message...');
else
dbms_output.put_line ('Failed to send message...');
end if;
end;
/

I get this error:

javax.mail.NoSuchProviderException: No provider for Address type: rfc822
at javax.mail.Session.getTransport(Session.java:475)
at javax.mail.Transport.send0(Transport.java:154)
at javax.mail.Transport.send(Transport.java:80)
at mail.send(mail:71)
Failed to send message...

I checked Metalink and it mentioned that the CLASSPATH needed to be updated with the location of the classes, did that and got the same result.

Tom Kyte
May 10, 2005 - 2:53 pm UTC

and did you do the above exactly... never had that problem myself.

NoSuchProviderException continued...

Stacey Jones, May 10, 2005 - 3:41 pm UTC

Yes.
Tom Kyte
May 10, 2005 - 11:17 pm UTC

sorry, never have encountered that problem myself. setting the classpath won't do a thing (the database has its OWN environment)




NoSuchProviderException continued...

Stacey Jones, May 11, 2005 - 8:39 am UTC

I forgot to mention I'm on 8.1.7.4 on HP UX. What versions of the mail and activation jar files did you download from Sun? Any other suggestions? Should I open a TAR?

Tom Kyte
May 11, 2005 - 8:56 am UTC

really old ones. (this thread is about 4 or 5 years old)

You can try a tar but I'm doubtful it would go very far - you are loading 3rd party code into the database as an application -- if all of the bits and pieces are not there, not much we can do.

appointment/meeting request from DB

Shiju, June 01, 2005 - 10:38 am UTC

Tom, Could you please explain how can we send a MS outlook appointment/meeting request from Oracle backend procedure?

Thanks


Tom Kyte
June 01, 2005 - 11:28 am UTC

not really, you'd have to tell me how to create an MS outlook appt/meeting first.

Re: appointment/meeting request from DB

A reader, June 02, 2005 - 3:03 am UTC

Can we call MS DLLs (using external proc) for achieving the same? If so, it would be great to get an example from you?

Thanks


Tom Kyte
June 02, 2005 - 4:35 pm UTC

I don't do windows.

But if you have expert one on one Oracle -- I have a rather EXTENSIVE chapter on how to do extprocs.

If you search this site, there are lots of examples


And they are well documented -- how to setup, use etc.

You have to write the integration code, your layer to be called from the database, I cannot do that.

Problem with execution

Byron Ward, June 06, 2005 - 3:57 pm UTC

When I execute this statement:

begin
afm.mail_pkg.send
( p_sender_email => 'sender@domain.com',
p_from => 'Oracle Database Account < oracle@domain.com >',
p_to => mail_pkg.array( 'user@domain.com','user1@domain.com' ),
p_cc => mail_pkg.array( 'user2@domain.com' ),
p_bcc => mail_pkg.array( 'user3@domain.com' ),
p_subject => 'This is a test',
p_body => 'Hello, this is the mail you need' );
end;

I get the following error:


afm.mail_pkg.send
*
ERROR at line 2:
ORA-06550: line 2, column 9:
PLS-00306: wrong number or types of arguments in call to 'SEND'
ORA-06550: line 2, column 9:
PLS-00306: wrong number or types of arguments in call to 'SEND'
ORA-06550: line 2, column 9:
PLS-00306: wrong number or types of arguments in call to 'SEND'
PL/SQL: Statement ignored

It seems to be a problem with the array, but I can't get it to accept it. If I take the arrays out and switch them to varchar2, I can send just fine. But this eliminates the funcionallity of multiple recipients that I need.

Any thoughts?

Thank you,

Byron


Tom Kyte
June 06, 2005 - 5:49 pm UTC

well, if you need to use afm.mail_pkg to call it, why not to reference the array?

are you logged in as AFM?
if not, do you have your own copy of mail_pkg in your current schema?

if you use the right type, afm.mail_pkg.array( .... ) what then?

Duh!!

Byron Ward, June 07, 2005 - 5:31 pm UTC

Sorry about the post.... I must be an idiot.

I can't believe I missed such a minor thing.

Thanks!

Why ñ/Ñ character are not displayed?

Eduardo, June 17, 2005 - 6:05 am UTC

Hi, I´m using the standards DEMO_BASE64 and SEND_MAIL packages for sending email through Oracle9i. But in Spain we have a special character (ñ). If I send an email using this special character I wouldn´t view it.

Can you help me?

Best Regards

Tom Kyte
June 17, 2005 - 2:58 pm UTC

if you base 64 encode the 8 bit data, it should transmit just fine. What do your recieved email headers look like? what is the character set of your database.

Eduardo, June 23, 2005 - 6:32 am UTC

Thanks, that works fine. I changed the write_data by write_raw_data



Client (Outlook) and Database in diferent language

Ricardo Patrocínio, June 29, 2005 - 8:49 am UTC

Hello Tom,

When I send e-mails to users with the e-mail client in a different language than the language in the database this client's can not understand the Date in the e-mail and always assume it to be January.

This is happening with a Database in English and a Client in Portuguese.

How can I solve this issue?


Thank you in advance,
R.P.


Tom Kyte
June 29, 2005 - 9:24 am UTC

read about the smtp protocol and send encoded messages?

I mean, what happens when you (using english) just email them (using portuguese) without a database after all..

SMS by PC to Mobile

Md. Tanweer Qasim, July 12, 2005 - 4:17 am UTC

Hi,
I need the detail how can I send a sms of Oracle Database information (e.g: send emp table's total record) to mobile.

How can I Communicate PC to any Mobile in the World.

What can I take the step from begin.
Can you provide the detail idea

Thanks
Regard
Tanweer

Tom Kyte
July 12, 2005 - 4:56 pm UTC

there is Oracle 10gAS wireless edition (middle tier)

of course, with most phones, you can email a text message to them as well, I use that a lot. utl_smtp or in 10g utl_mail will do that well

utl_smtp.open_connection

Ujif, August 24, 2005 - 3:24 am UTC

Hi Tom.
I've written a procedure which uses the utl_smtp to send
a email to myself. When I run the procedure on this point:
mail_conn := utl_smtp.open_connection(mailhost, 25)

the following error occurs:
ORA-29532: Java call terminated by uncaught Java exception: java.lang.ExceptionInInitializerError
ORA-06512: at "SYS.UTL_TCP", line 678
ORA-06512: at "SYS.UTL_TCP", line 671
ORA-06512: at "SYS.UTL_SMTP", line 99
ORA-06512: at "SYS.UTL_SMTP", line 121
...

Tom Kyte
August 24, 2005 - 10:55 am UTC

version, java stuff loaded?

Sending mail with characters of spanish language

Alvaro, October 12, 2005 - 12:55 pm UTC

Hi Tom:

This question answer me on how to send characters of spanish language.

Thanks,

Alvaro Alonso
Bogota, Colombia (South America)
2005-10-12

Tom Kyte
October 12, 2005 - 2:24 pm UTC

Tracking Bounce Emails

Ravi Kumar, October 13, 2005 - 7:25 am UTC

Hi Tom..

It is very very useful thread for me, I have read about the UTL_SMTP package and applied in my project to send emails from our Application. And It is working fine, thanks to you :).

Now I need to do something to track bounced emails.

Currently My Application sending the emails like this.

1. Selection Screen (From Where we can select the persons to send an email)

2. Inside the loop I am sending the emails to the selected persons one by one and generating a History Sequence No for each email and storing the details in Email_History Table.

Now What I want to do is..., I want to send this History Sequence No with each email in a Hidden way, So that if the mail bounce back, I can get this History Sequence No Back and can trace it in my History Table. can you please suggest me what is the best method to do that. (I mean How to send the History Sequence No with each Email so that I can get it back in all type of bounces)

Thanks & Regards
Ravi Kumar..



net send through the db

Dan, October 19, 2005 - 9:29 am UTC

In our development environment, whenever someone wants to take down a database they do a "net send *" which alerts a lot of people whether or not they care about this...
I tested to see if "net send /users" knew about database sessions and it didn't.
Is there any way to throw a message to the screen of everyone that has a database session?

Tom Kyte
October 19, 2005 - 9:44 am UTC

you'd have to query the database and feed that to "net send".

net send through db

Dan, October 19, 2005 - 9:57 am UTC

OK, so I've got this:

DECLARE
CURSOR c
IS
SELECT DISTINCT osuser
FROM v$session
WHERE osuser != 'SYSTEM';
BEGIN
FOR r IN c LOOP
host (net send '||r.osuser||': database going down');
END LOOP;
END;
/

but I've tried a couple variations of the actual "net send"
part of it, and can't find any that are legal...

Thanks.

Tom Kyte
October 19, 2005 - 12:30 pm UTC

there is no "host" command in plsql persay, a sqlplus script could be:


set feedback off
set heading off
set pagesize 99999
set trimspool on
set echo off

spool tmp.sql
begin
for x in ( select distinct osuser from v$session where osuser <> 'SYSTEM')
loop
dbms_output.put_line( 'host net send ....' );
end loop;
end;
/
spool off
@tmp.sql


(not tested, but the gist is there...)


Email within 10g

Jasbir Kular, October 19, 2005 - 8:06 pm UTC

Hi All,

10g comes with JavaMail and I was able to compile and run the "mail" java program provided at the beginning of this thread without having to loadjava the Sun javamail classes. I wanted to do this because UTL_MAIL seems limited to only RAW and VARCHAR2 attachments. I wanted to easily use BFILE attachments. The "mail" java program provided by Tom and his team is excellent and I think that program or some variation of it should be used for the implementation of UTL_MAIL. The current form of UTL_MAIL seems like a layer on top of UTL_SMTP.

Thanks.


Required some clarification

Mousumi Ghosh, October 20, 2005 - 7:10 am UTC

When we attach a file in case of sending e-mail from pl/sql
we can use
1.SYLK file format.
2.HTML
Using HTML we can create the file and format it as we required.
Then why should we use SYLK file format.
I am working in Oracle 10g.
Is it for the older version of Oracle where we can't use HTML in PL/SQL code? or for all versions of Oracle we can use HTML.
Please clarify why should we use SYLK file format?

Tom Kyte
October 20, 2005 - 8:33 am UTC

use the format you want to use???

send mail through oracle9i - Need little more help-urgent

Priya Job K, October 27, 2005 - 6:55 am UTC

i want to get the ip address of my server programmatically
to set mailhost . now it is fixed as local host.
Please help as early as possible

Tom Kyte
October 27, 2005 - 7:01 am UTC

select host_name from v$instance;


the hostname is what you need.  You can also:


ops$tkyte@ORA10GR2> select utl_inaddr.get_host_address, utl_inaddr.get_host_name from dual;

GET_HOST_ADDRESS
-------------------------------------------------------------------------------
GET_HOST_NAME
-------------------------------------------------------------------------------
192.168.0.75
me
 

Randy, November 14, 2005 - 11:26 am UTC

Tom,
I have a question about using the date with DBMS_JOB. I have the following code in my HTML_EMAIL procedure.


------

select sessiontimezone into timezone_ora from dual;

timezone_info := substr(timezone_ora,1,3) || substr(timezone_ora,5,2) || ' (GMT)';

l_date := to_char(SYSDATE,'dd Mon yy hh24:mi:ss')|| timezone_info;

l_connection := utl_smtp.open_connection( p_smtp_hostname, p_smtp_portnum );
utl_smtp.helo( l_connection, p_smtp_hostname );
utl_smtp.mail( l_connection, p_from );
utl_smtp.rcpt( l_connection, p_to );


l_temp := l_temp || 'Date: '|| l_date || chr(13) || chr(10);
l_temp := l_temp || 'MIME-Version: 1.0' || chr(13) || chr(10);
l_temp := l_temp || 'To: ' || p_to || chr(13) || chr(10);
l_temp := l_temp || 'From: ' || p_from || chr(13) || chr(10);
l_temp := l_temp || 'Subject: ' || p_subject || chr(13) || chr(10);
l_temp := l_temp || 'Reply-To: ' || p_from || chr(13) || chr(10);
l_temp := l_temp || 'Content-Type: multipart/alternative; boundary=' ||
chr(34) || l_boundary || chr(34) || chr(13) ||
chr(10);
-------------------------------------------------------

When I execute the HTML_EMAIL procedure directly within SQLPlus the date in the mail client is correct. However, when the procedure is called using DBMS_JOB next_date, next_sec the date always comes back 1 day behind at 7:00 p.m. I can not understand why DBMS_JOB would be causing this change. Any thoughts on this?

Thanks,
Randy

Tom Kyte
November 14, 2005 - 2:08 pm UTC

you do not show the dbms_job call???!?! that is the only important part here.

A reader, November 15, 2005 - 8:35 am UTC

The dbms_job only calls the procedure. For example,

declare jobno number;
BEGIN
DBMS_JOB.SUBMIT(jobno,
' begin
PEOBCT_WSAR;
end;', TRUNC(SYSDATE) + 05/24, 'NEXT_DAY(TRUNC(SYSDATE), ''MONDAY'') + 05/24');
END;

The PEOBCT_WSAR sends out the email messages..

as
begin
html_email(
p_to => 'user',
p_from => 'from database',
p_subject => 'subject',
p_text => 'WSAR can be viewed in HTML',
p_html => 'email message from database....',
p_smtp_hostname => 'smtp.server',
p_smtp_portnum => '25');
end;

When I run the dbms_job manually the date/time is correct in the client. When Oracle runs the DBMS_JOB the date/time is incorrect and always one day behind @ 7:00 pm. That is the part that makes no sense to me...

Tom Kyte
November 15, 2005 - 11:39 am UTC

show me what you mean by "incorrect" - are you saying the next_date is getting set wrong.

It seems that next date would ALWAYS be a monday at 5am. show me what you see.

A reader, November 15, 2005 - 12:50 pm UTC

The dbms_job next_date is correct. The date that displays in the email client is not correct. The date in the client is correct if I run the procedure and/or dbms_job manually. It is not correct - off by approx 1 day and always 7:00 p.m. - in the email client.

Thanks,
Randy

Tom Kyte
November 15, 2005 - 2:33 pm UTC

I'll bet your timezone on the server is "wrong".

check that out - the server timezone sounds wrong.

Bidyut Shah, December 13, 2005 - 8:42 am UTC

Hi Tom,

The information is very very useful. But what I see is that the mails can be send to same domain, like if I can send mail from abc@xyz.com to pqr@xyz.com, but if I want to send mail from abc@xyz.com to abc@pqr.com

Please advice.

Thx ... Bids

Tom Kyte
December 13, 2005 - 9:47 am UTC

ask your network/system administrators - they are the ones that configure the SMTP servers. They have undoubtedly disallowed relaying in order to not be used by spammers.

ORA-29278: SMTP transient error: 421 Service not available

Ram, December 17, 2005 - 10:09 am UTC

Hi,
My client wants to address a section of Customers, and wants to send promotional mails. I have written a procedure for sending mails. I am picking the recepient email ids from the database. My procedure runs fine, if addressed to a small number of customers (say upto 1000), when increased, I get this error
ORA-29278: SMTP transient error: 421 Service not available
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 374
ORA-06512: at line 301
ORA-29278: SMTP transient error: 421 Service not available
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 374
ORA-06512: at line 272
ORA-29278: SMTP transient error: 421 Error: timeout exceeded
ORA-29278: SMTP transient error: 421 Service not available
I am not able to figure out where the issue could be.
Can u pls help me ?

Regards,
Ram

Tom Kyte
December 17, 2005 - 11:18 am UTC



talk to your SA or network guys, you do not have a SMTP server setup at the place you are trying to get to. You need to ask them "so, what is the correct host name and port number for me to use to send email over SMTP from this server?"

SMTP issue

Ram, December 19, 2005 - 4:42 am UTC

Actually, I am able to open, handshake and close connections (without any text messages, only the connections), through the same procedure. The connection is getting established 'n' number of times I am scheduling it for. But, when the message to be sent is being put, it sometimes sends 800 mails or sometimes 1 mail, after which the connection hangs. I am establishing the connection in the loop for every record. I also logged only the records that are being fetched, without the connection, and it is also working fine, which means there is no issue with the procedure.
Is there any issue in sending from a db which is shared server?

Regards,
Ram

Tom Kyte
December 19, 2005 - 7:36 am UTC

you are hitting your smtp server too hard and fast then, it cannot keep up. sleep for a bit between emails, give it a chance.

problem *not* in database.

email

mo, February 13, 2006 - 5:47 pm UTC

Tom:

1. Is there a way to confirm if the email was sent from the smtp server to the destination and track that?

2. Does this package success means that the email was sent to the smtp server only but you do not know what happens afterwards (reached destination)?

thanks,

Tom Kyte
February 13, 2006 - 5:51 pm UTC

1) hah, no.

2) correct. It does not mean the recipient will ever actually get it, as with all email

Warren Tolentino, February 23, 2006 - 3:57 pm UTC

Tom,

What is the number of characters allowed to pass a value to the parameter p_send_email for the "utl_smtp.mail(g_mail_conn, p_sender_email)".

Thanks,
Warren



Error to get POP3 mail

Kato, February 24, 2006 - 11:18 am UTC

Hi Tom:

I want to read POP3 mails with a PLSQL function, then i loaded the java mail apis into Oracle Database 9i R2. and gave this grants:

begin
dbms_java.grant_permission(
grantee => 'USER',
permission_type => 'java.util.PropertyPermission',
permission_name => '*',
permission_action => 'read,write,execute'
);
dbms_java.grant_permission(
grantee => 'USER',
permission_type => 'java.net.SocketPermission',
permission_name => '*',
permission_action => 'connect,resolve'
);

DBMS_JAVA.GRANT_PERMISSION('USER', 'SYS:java.lang.RuntimePermission', 'writeFileDescriptor', '');
DBMS_JAVA.GRANT_PERMISSION('USER', 'SYS:java.lang.RuntimePermission', 'readFileDescriptor', '');
end;
/

GRANT JAVAUSERPRIV TO USER;

After i created this class:

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "GETMail"
AS import java.io.*;
import java.sql.*;
import java.util.Properties;
import java.util.Date;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;
public class GETMail {
public static oracle.sql.NUMBER getMail(String host, String username, String password) throws Exception
{
int rc = 1;
String cFrom;
String cTo;
String cSubject;
String cData;
// Create empty properties
Properties props = new Properties();
// Get session
Session session = Session.getDefaultInstance(props, null);
// Get the store
Store store = session.getStore("pop3");
// Connect to store
store.connect(host, username, password);
// Get folder
Folder folder = store.getFolder("INBOX");
// Open read-only
folder.open(Folder.READ_ONLY);
try
{
BufferedReader reader = new BufferedReader (
new InputStreamReader(System.in));
// Get directory
Message message[] = folder.getMessages();
for (int i=0, n=message.length; i<n; i++) {
cFrom = message[i].getFrom()[0].toString();
cSubject = message[i].getSubject().toString();
cData = message[i].getContent().toString();
// Display header
System.out.println(i + ": " + message[i].getFrom()[0]+ "\t" + message[i].getSubject());
// Display message content
System.out.println(message[i].getContent());
// Store from field and subject
#sql { INSERT INTO MAIL_USER ( MLU_FROM , MLU_TO , MLU_SUBJECT , MLU_DATA , MLU_FECHA_REC)
VALUES(:cFrom,'2',:cSubject,:cData, SYSDATE) };
System.out.println("INSERT Ok");
}
} catch (Exception e)
{
e.printStackTrace();
rc = 0;
} finally
{
// Close connection
folder.close(false);
store.close();
return new oracle.sql.NUMBER(rc);
}
}
}
/

And this function:

CREATE OR REPLACE
function getmail(
host in varchar2,
username in varchar2,
password in varchar2) return number
as
language java name 'GETMail.getMail( java.lang.String,
java.lang.String,
java.lang.String
) return oracle.sql.NUMBER';
/

And tryed to real mail with:

declare
cCad number(10);
begin
cCad := getMail('intranet.mail.server','user','password');
dbms_output.put_line('ret='||cCad);
end;

The result is:

1) If mail account for user don't have mail, NO ERROR: getMail return 0
2) If mail account for user have mail, this is the ERROR:

java.lang.SecurityException: cannot read <Resource Handle: META-INF/mailcap.default|SYS|431> because USER does not have execute privilege on it
at oracle.aurora.rdbms.SecurityManagerImpl.checkRead(SecurityManagerImpl.java)
at oracle.aurora.rdbms.Handle.inputStream(Handle.java)
at oracle.aurora.rdbms.url.jserver.JserverURLConnection.getInputStream(JserverURLConnection.java)
at java.net.URL.openStream(URL.java)
at java.lang.ClassLoader.getResourceAsStream(ClassLoader.java)
at java.lang.Class.getResourceAsStream(Class.java)
at javax.activation.MailcapCommandMap.loadResource(MailcapCommandMap.java:173)
at javax.activation.MailcapCommandMap.<init>(MailcapCommandMap.java:162)
at javax.activation.CommandMap.getDefaultCommandMap(CommandMap.java:55)
at javax.activation.DataHandler.getCommandMap(DataHandler.java:146)
at javax.activation.DataHandler.getDataContentHandler(DataHandler.java:578)
at javax.activation.DataHandler.getContent(DataHandler.java:511)
at javax.mail.internet.MimeMessage.getContent(MimeMessage.java:1339)
at RecuperaMail.getMail(RecuperaMail.java:39)
salida=0

The error is in this sentence:
cData = message[i].getContent().toString();

I tried:

GRANT EXECUTE ON "META-INF/mailcap.default" TO USER;

But nothing, it generated this error:

ORA-04042:procedure, function, package, or package body does not exist

I don't understand How Do i assign this grant?

Thanks for your help.


Kato.




Tom Kyte
February 24, 2006 - 11:40 am UTC

 
sys@ORA10GR2> grant execute on java resource "META-INF/mailcap.default" to ops$tkyte;
 
Grant succeeded.
 
 

Attach File Direct to mail

Debasish Ghosh, March 10, 2006 - 6:13 am UTC

Excellent. I use your code and it's running quite well. thanks for that, but I want to attah file directly with mail( as we do in normal mail) not through BLOB.

Thanks for advance
Debasish

Tom Kyte
March 10, 2006 - 12:25 pm UTC

ummm, well, don't know what to say here.


You are not running "outlook" or whatever you run on your pc in the database right...

and given that outlook or whatever just lets you pick a file from the operating system....

and that a file is just another word for "blob" in effect.


tell me - what is meant by "attacht directly with mail"???? that doesn't compute.

and remember, we are writing software here, to run in the database, not pushing buttons on a gui.

Failing to load into Linux

Debasish, April 25, 2006 - 2:45 am UTC

Win windows it is running fine.

but I am trying to unjar the mail.jar and activtion.jar file into linux through loadvjava.

$ loadjave not found.

pl. help me and tell the procedure what i have to follow in Linux for sending mail through java procedure.


Tom Kyte
April 25, 2006 - 5:37 am UTC

it should be there, look again. I am assuming of course the dba installed that component (the java stuff)

What is JAVA STUFF

Debasish, April 26, 2006 - 6:06 am UTC

actully we have no DBA, pl. instruct me how to load lava Suuff on Linux

Tom Kyte
April 26, 2006 - 8:15 am UTC

talk to the guy that installed the software, they must have read the installation guide right - they know how to use dbca and add/remove software components.

Or utilize support for installation and configuration issues.


(hey - who is backing up your databases? Please ask them to "try a restore, just to prove you can do it" - today, really fast)

HTML emails

Emad Kehail, June 05, 2006 - 2:31 am UTC

Thanks Tom for this great idea. I have used successfuly with attatchements.

However, I could not send HTML formatted emails using JavaMail API.

How could I send attachments along with HTML emails using the JavaMail API???

Thanks in advance
Emad

Tom Kyte
June 05, 2006 - 7:45 am UTC

search this site for html email


</code> http://asktom.oracle.com/pls/ask/search?p_string=html+email <code>

the html is "an attachment"

Sending too many emails take so long time

Emad Kehail, June 06, 2006 - 7:18 am UTC

Thanks Tom for your quick reply. I have already used the package developed at

</code> http://www.oracle.com/technology/sample_code/tech/pl_sql/htdocs/Utl_Smtp_Sample.html <code>

to send emails from Oracle. I am sending HTML formatted emails, either with attachements or not.

However, when I try to send emails to many recipients, say 10,000 emails, it takes so much time.

I have followed your idea and I have submit it as job, but I have noticed that this job took 11200 sec to send 10000 emails.

I have disabled the line that sends the email and I have ran the job again, it took only few seconds (2-3 seconds only).

My friend has told me this could be because of the handshaking the UTL_SMTP package is doing with the email server. The UTL_SMTP package has to establish a connection each time it needs to send an email!.

I have optimized the code, so instead of sending indvidual emails, I have concatenated 50 emails, which is the maximum limit I can use, to send them as once as BCC. The speed improved, but just so little.

The time reduced from 11200 seconds to be 7349 seconds.

I have read in this thread that you are using this at Oracle to send thousands of emails daily.

Would you please point me where I could have done something wrong?? Where I can improve the speed of sending emails?

Thanks
Emad

Tom Kyte
June 06, 2006 - 8:46 am UTC

smtp *ain't fast* that way.

you sent 10,000 (thousands) of emails in about 3 hours. You just showed how that can happen?

You have done it correctly with the bcc - if you are sending the same exact email, you should bcc as many people as you can (send one email, not one email per person)

So, why just "50"?

Thanks

Emad Kehail, June 06, 2006 - 11:46 pm UTC

Thanks Tom for this quick helpful reply.

Regarding the 50 emails, it is because the university IT policy, where I work, has determined the maximum limit for any email sent to contain only 50 email addresses!!!. Unfortunately, this has been applied to the mailing system we have implemented.

Before, we were BCCing as many as we can and send the email as once.
Anyhow, you had, and still, make it clear for me where is the problem. I already expected it to be as I mentioned before.

Thanks again and again for your continuous help and efforts.

Emad

Tom Kyte
June 07, 2006 - 6:52 am UTC

tell the university IT community that because of their rule, they need to buy you 10 more smtp servers.



Formatting in UNIX mails

Pretaish, June 07, 2006 - 12:52 pm UTC

Hi Tom,

Currently I am sending emails to my clients through sendmail utility of UNIX. These mails contain details of various stock market deals. Now, they want the email text to be formatted. E.G. the headers should be in Bolds..

Please let me know how it can be accomplished.

Regards

But I am not using Utl_Smtp

pretaish, June 08, 2006 - 6:53 am UTC

Hi Tom,

Thanks !

The link given by you describes the means to format mails sent through Utl_Smtp. But I need to send mails directly from UNIX using SENDMAIL, without any involvement of Database.
Could you please suggest any such link to me.

Thanks in Advance

Tom Kyte
June 08, 2006 - 9:18 am UTC

...
without any involvement of Database.
......


That does not compute. You just lost me. :)

Umm, I sort of do "this database thing"

If you want to do something "outside of the database", well, this would not be the right place to ask.

Java problems

Mike Friedman, July 03, 2006 - 6:58 am UTC

We're trying to implement this in a 10gR1 DB.

When we run the line

Transport.send(msg);

We throw an error - Exception: java.lang.ExceptionInInitializerError.

Note: We originally had other problems but we dropped the mail.zip and reinstalled with 1.3.1 and that went away.

Anyway, when we check dba_java_classes we see that javax/mail/Transport has Kind "INTERFACE". That can't be right - shouldn't it be a class?

Where can we go from here?

Do we also need to downgrade JAF?

Tom Kyte
July 07, 2006 - 3:23 pm UTC

the utl_mail package in 10g supports attachments, have you considered just using that rather than loading external java packages?

About mail with attachment

Gladys, July 20, 2006 - 5:26 pm UTC

Hi Tom, the topic is very usuful for me, thank you.
I have 9i and I have other questions, I am using the demo mail Packages thet I get this page, this is great, but if I want sent .pdf attachment in a local pc, how can I read the attachment to encode it and sent.
Thank you

Tom Kyte
July 22, 2006 - 5:28 pm UTC

you sort of have to get it into the database where PLSQL (which is sending the mail) runs.

About mail with attachment

Gladys, July 24, 2006 - 10:31 am UTC

Yes Tom, I understood, but my question is if I use this code to read and encode a file in http place, how can I the same operation (read and encode), with which procedure for read an encode a file in a directory in a local pc ?
The code is :

req := utl_http.begin_request('</code> http://192.168.1.5/webShared/Attachm/'||PAttachment <code>;
resp := utl_http.get_response(req);

BEGIN
LOOP
utl_http.read_raw(resp, data, demo_mail.MAX_BASE64_LINE_WIDTH);
demo_mail.write_raw(
conn => conn,
message => utl_encode.base64_encode(data));
END LOOP;
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(resp);
END;

Here I use utl_http procedure. In a local computer, no http place what procedure Can I use ?
Thank you so much.

Tom Kyte
July 24, 2006 - 11:01 am UTC

I'll say it again: you have to get the file to the database server, unless and until you do - you will NOT be attaching it to anything coming from the database server!

It would be very virus like if we could reach back to your machine and just pick up any file we wanted wouldn't it.

About mail with attachment

Gladys, July 24, 2006 - 12:21 pm UTC

Sorry Tom, I don't explain you well. I have the file in a directory in my Database server, but my http server is other, and with this procedure I can not get nothing from my database server.
Thank you


Tom Kyte
July 24, 2006 - 2:51 pm UTC

now, I am really not following you.

"i cannot get nothing from my database server"?


I don't know what you mean. what does the http server have to do with anything??

if you are sending email via PLSQL - it starts with the database server, ends with the database server and never has anything to do with anything else other than the database server.

local pc - don't mention it, doesn't count, cannot access it.
http server (another server, any other server) - don't mention it, doesn't count, cannot access it.


it is all about stuff on the database server - that is all you have access to - period.

About mail with attachment

xgla, July 31, 2006 - 10:06 am UTC

Hi, Tom, finally I understood you.
In this moment, I has un bfile in the data base with a pointer to my file, but I am trying to read it with this code, but It doesn't working

declare
MyFile BFILE ;
v_Amount BINARY_INTEGER := 57 ;
v_Position INTEGER := 1 ;
BuffFile RAW(1024) ;
begin
Select Attachm into MyFile
from twf.Attachm_Temp
where secu = PSecu ;
IF (DBMS_LOB.FILEEXISTS(MyFile) != 0) then
flag := 12 ;
end if ;
If DBMS_LOB.FILEISOPEN(MyFile)<> 1 then
DBMS_LOB.OPEN(MyFile, DBMS_LOB.LOB_READONLY);
end if ;

LOOP
BuffFile := DBMS_LOB.SUBSTR(MyFile, 255,v_Position);

demo_mail.write_raw(
conn => conn,
message => utl_encode.base64_encode(BuffFile));
flag := flag + 1 ;
v_Position := v_Position + v_Amount ;
END LOOP;
DBMS_LOB.CLOSE (MyFile);
EXCEPTION
WHEN NO_DATA_FOUND THEN
flag := 11 ;
end ;
end ;

The DBMS_LOB doesn't working, I don't know why, the procedure lost here, and not return the variable flag.
What other procedure could I use instead DBMS_LOB to read my BFILE ?
Thank you so much.
Bye xgla


Tom Kyte
July 31, 2006 - 10:17 am UTC

"my car isn't working"

"why"?

Nope, I won't tell you the error message on the console.
I won't describe the sounds it makes.
I won't tell you the operating environment (for example, no, I won't tell you if I fill the gas regularly, have the oil changed and so on).

so, why isn't my car working? It is a Toyota Prius (that is my code).

About mail

Gladys, July 31, 2006 - 10:16 am UTC

Tom, I have other question about mail. I have 9i data base, but I am working in 10g forms builder. I am trying to send email directly for report, and I am getting the error REP-50159. I am looking for in the report documentation, and I get this :
REP-50159: Executed successfully but there were some errors when distributing the output

This error can occur for a number of reasons when sending report output to an e-mail destination.

Cause 1: Mail server is not configured properly.

Action 1: Configure the mail server in the server configuration file (ORACLE_HOME\reports\conf\server_name.conf) and the Reports Builder configuration file (ORACLE_HOME\reports\conf\rwbuilder.conf). The pluginParam element should specify the outgoing SMTP server name. For example:

<pluginParam name="mailServer">smtpserver.mycompany.com</pluginParam>

For more details, refer to the chapter "Configuring OracleAS Reports Services" in Oracle Application Server Reports Services Publishing Reports to the Web.

Cause 2: The mail server is not responding or is not up and running.

Action 2: Check if the mail server is up and running and is responding in a timely manner. You can use your Microsoft Outlook client to connect to the mail server and check the status.

Cause 3: A valid recipient e-mail address is not specified for the desname keyword.

Action 3: Specify a valid recipient e-mail address for the desname keyword.

Cause 4: The mail server is SSL-enabled. SSL = Secure Sockets Layer

Action 4: Use a non-SSL mail server. Oracle Reports does not support SSL-enabled mail servers to send e-mail.

I checked all of causes, and everythig is ok in my server. I am sending to my own email address, the smtp server is well configurated, my mail server is workig ok, and it doesn't is a SSL mail server.
Could you give me any suggestion ?
Thank you so much
Bye Gladys

Tom Kyte
July 31, 2006 - 10:25 am UTC

sorry, never have used reports myself. suggest you use the otn.oracle.com discussion forums, there is one for forms/reports.

want to semd e-mail

A reader, August 02, 2006 - 11:52 am UTC

want to semd e-mail when cpu utilization is more than 80% on windows and unix both.
what is the parameter to capture cpu_utlization


Tom Kyte
August 02, 2006 - 12:35 pm UTC

that is sort of an OPERATING SYSTEM fact, not a database fact.

Look to your OS. Enterprise Manager can actually do this for you - are you running any sort of systems management tool?

(and be prepared to get slammed with email, 80% is pretty "low" not to be hitting it normally from time to time)

how can we do it from oem

A reader, August 02, 2006 - 3:36 pm UTC

how can I do it from oem.
couldn't find anything

Tom Kyte
August 03, 2006 - 9:00 am UTC

10g EM - reports on everything from the OS on up. It is just there (right on the front page in fact) of the application itself.



cpu utilization

A reader, August 03, 2006 - 12:05 pm UTC

is there any parameter in oracle to capture cpu utilization.

Tom Kyte
August 03, 2006 - 4:20 pm UTC

of the database? v$sysstat has that and tons more.




v$osstat

A reader, August 03, 2006 - 2:23 pm UTC

What I found from net that there is v$osstat but there busy_ticks , idle ticks doesn't give substabtila information to be used.

Awesome

bc, August 14, 2006 - 3:37 pm UTC

Tom,

Your explanations and examples are awesome. I have been using the javamail based send function for a while now and works it great everytime.

I was wondering as to what needs to be changed ( In the JavaMail based send function ) if I need to send the body in html format ?

Thanks
BC

Thanks

BC, August 15, 2006 - 10:21 am UTC

Tom,

Thanks for the quick reply.

BC

user authentication

Thomas, August 18, 2006 - 5:22 am UTC

Hi Tom,

is there a way to implement user authentication in the java stored procedure? Similar to:
utl_smtp.command(c, 'AUTH LOGIN');

Kind regards
Thomas

Tom Kyte
August 18, 2006 - 8:22 am UTC

authentication to WHAT exactly (please don't say "the database" since if you are running a java stored procedure you are already authenticated of course)

user authenication

Thomas, August 21, 2006 - 8:17 am UTC

Sorry, for my unexact question!

We have to authenticate at the mail-server. In our project this is a MS Exchange Server 2003 and we have to authenticate by username and password. In utl_smtp we use the commands:

utl_smtp.command(c, 'AUTH LOGIN');
utl_smtp.command(c, demo_base64.encode(utl_raw.cast_to_raw(i_username)));
utl_smtp.command(c, demo_base64.encode(utl_raw.cast_to_raw(i_pwd)));

Is there a similar way in your java stored procedure?

Thank you for your help!
Thomas

Tom Kyte
August 27, 2006 - 9:10 am UTC

I don't know, I've never used MS exchange. This really isn't an Oracle question as all you need is "java" plus "MS exchange" to get it working - once you figure that out, we can load that java into the database.

For file in local PC can't i use UTL_SMTP?

Mpals, September 22, 2006 - 10:38 am UTC

"local pc - don't mention it, doesn't count, cannot access it."
This is still true for ORACLE 10g?
Can i use UTL_SMTP for sending emails with local pc files attach?

Tom Kyte
September 22, 2006 - 3:45 pm UTC

utl_smpt runs, has run, will run, will always run...

on the server. server must be able to see files one way or the other


client can copy file to server (blob)

Useful information

Karthik, September 25, 2006 - 1:47 am UTC

This is a good information.

Calling Java Procedure in PL/SQL

v k ravi, September 28, 2006 - 8:22 am UTC

Hi tom
i'm calling a java program in a pl/sql function
but it's showing this error
ORA-29549: class IMIS.JDelete has changed, Java session state cleared

Here is my code
=======================================
import java.io.*;
public class JDelete
{
public static int delete(String filename)
{
File f = new File("\\\192.168...\\d:\\"+filename);
boolean b = f.delete();
if (b)
return 1;
else
return 0;
}
}
=======================

loadjava -user imis/imis@imis -resolve JDelete.class
===============================
create or replace function fdelete
(fine in varchar2) return number
as
language java
name 'JDelete.delete(java.lang.String) return int';
======================================
select fdelete('Ravi.class') from dual;
=> it return 0
while file exists there

======================================
my System environment is
OS XP SP2
DB 9.2i
java jdk1.4

thx
v k ravi


Tom Kyte
September 29, 2006 - 5:51 am UTC

that happens when the java is recompiled after you called it once, just call it again.

basically the code was wiped out

A reader, October 03, 2006 - 1:12 am UTC

I had execute again, but it doesn't do any thing
thx & regards
v k ravi

Tom Kyte
October 03, 2006 - 6:18 am UTC

and if you reconnected?

V K Ravi, October 04, 2006 - 3:14 am UTC

hi Tom

Now it's working.
But i'm now facing new problem.
My requirement is that i have to call IExplorer.
My database is loaded on Linux 9.
for which i have written following code & give following permissions :-

grant javasyspriv to vinay;
dbms_java.grant_permission('VINAY','java.io.FilePermission','/usr/bin/mozilla','execute');

import java.lang.*;
class ExecDemo
{
public static void caal(String s)
{
Runtime r = Runtime.getRuntime();
Process p = null;
Thread t = Thread.currentThread();
try
{
p = r.exec(s);
}
catch(Exception e)
{System.out.println(e);}

}
}
CREATE OR REPLACE
procedure fexc(p_name IN VARCHAR2)
AS
LANGUAGE JAVA
NAME 'ExecDemo.caal(java.lang.String)';


when i'm executing this code on linux(where my DB is loaded)
it's working fine.
Begin
Fexc(‘/usr/bin/mozilla’);
End;

but when i execute this procedure from other system(say a client system with windows env.) it's not run mozilla.
what's the problem?
is any other permission required to call remote executable
file, but in my previous code (for deleting file) it's deleting file of remote machine.


Tom Kyte
October 04, 2006 - 7:05 am UTC

umm, the code runs on the server, not on the client, even if you got iexplore to start, you would never be able to see it, it doesn't run as you on your terminal

What precisely are you trying to accomplish here?????

V K Ravi, October 04, 2006 - 7:36 am UTC

On our's ERP on some places i have to send sms to clients
which depends upon conditions, so i have to make that program in backend(it's working fine from Forms6i but after running that URL i havn't any control to close IE and it must require internet connection on client for that reason i have choose java).
For sending SMS i have to start IE on server with an URL.
after some time(say 1 or 2 sec.) IE will be closed. so my work will be done, but i hang here.I'll be very pleased if u help me out.
thx & regards
ravi


Tom Kyte
October 04, 2006 - 5:02 pm UTC

better find "a better more reliable" way to do this.

I serioulsy DOUBT you need IE

I think you might need something that can "do a url"
That could be utl_http

but IE will have absolutely nothing at all to do with it.



ravi, October 06, 2006 - 2:38 am UTC

Ok tom i know that this is not a proper solution,
and rightnow i'm trying to use java.net package.
Hope here i'l get solution.
But i still wondering whyn't my procedure was working if
i was executing procedure from client side.
is any priviliges missing? what's the reason?
thx
ravi

Tom Kyte
October 06, 2006 - 8:59 am UTC

umm, because IE is a "gui" that needs "a screen", and you don't "have one" in the database.


This ain't unix.

Read mails and write to a table

Nikhil, November 14, 2006 - 7:42 am UTC

Hello Tom,
I want to read an E-Mail, extract attachments (Text or Excel) and write it to a table.

Can you give me some suggestion or steps as to how to go about? I'm using Oracle 10g.

Thanks


Tom Kyte
November 14, 2006 - 8:08 am UTC

well, when you have figured out how to read an email, extract the attachments - and have the attachments, we can help you out with getting them into a BLOB:

</code> http://docs.oracle.com/docs/cd/B19306_01/appdev.102/b14249/toc.htm <code>

Emu, November 15, 2006 - 1:07 am UTC

Adding attachments can be quite easy - when they are plain text anyway. I've been sending mulitiple attchments this way for ages safely without the need for hundreds of lines of code! So if your sending basic attachments probably no need to use the java library, just do it yourself using utl_tcp.

Really its simple enough and I'm sure you can google up an example. I did.

Sending Email form Developer 6i and Oracle 9i

Razaul Karim, November 20, 2006 - 5:21 am UTC

Mr. Tom,

I have followed UTL_SMTP accordingly for sending email from Developer 6i Forms. It is working well when I sending single line in message. But, I want to send multi-line message. When send the multi-line message then it is not working and giving the following error:

ORA-29278

Please give me a solution, I will be very grateful to you.


Tom Kyte
November 20, 2006 - 1:37 pm UTC

$ oerr ora 29278
29278, 00000, "SMTP transient error: %s"
// *Cause: A SMTP transient error occurred.
// *Action: Correct the error and retry the SMTP operation.


i guess retry, i mean, what else can one say - it is hard to debug your code without seeing your code.

and if your code is not TINY, we don't want to see it.

Great Help

Mandeep, November 23, 2006 - 4:27 am UTC

Dear Tom,
The example and steps given are the best help anyone interested in sending e-mail with attachments from Oracle can get. Thanks to you.

I am facing a little problem.. may be you can guide me on that..

I implemented the steps suggested in the example for sending e-mail with attachements from orcale 9i (Windows) and everything was working perfect.

Now, I implemented the same steps on Oracle 9i (Unix) in a different environment and different exchange server but the same application installation, the email is received without any body & attachments.

I compared the "Internet Headers" of the e-mails from two installations and there seems to be something missing in the later one.. have a look...

-----------------------------------------------------------
----Oracle 9i (Windows) E-Mail Internet Headers-----

Microsoft Mail Internet Headers Version 2.0
Received: from <server name> ([10.112.98.57]) by <exchange server> with Microsoft SMTPSVC(6.0.3790.1830);
Wed, 20 Sep 2006 21:09:01 +0530
Message-ID: 640014161.21158766743408.JavaMail.javamailuser@localhost
Date: Wed, 20 Sep 2006 21:09:03 +0530 (IST)
From: <from id>
To: <to id>
Subject: Product costs
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_2_-694063661.1158766743408"
Return-Path: <from id>
X-OriginalArrivalTime: 20 Sep 2006 15:39:01.0141 (UTC) FILETIME=[E5139C50:01C6DCCA]


------=_Part_2_-694063661.1158766743408
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


------=_Part_2_-694063661.1158766743408
Content-Type: Text/csv; name=10862009.csv; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=10862009.csv


------=_Part_2_-694063661.1158766743408—
-----------------------------------------------------------
----Oracle 9i (Unix) E-mail Internet headers-----

Microsoft Mail Internet Headers Version 2.0
Received: from <server name> ([10.10.11.107]) by <exchange server name> with Microsoft SMTPSVC(6.0.3790.1830);
Thu, 23 Nov 2006 10:12:21 +0800
Message-ID: <-1445021043.11164247919094.JavaMail.javamailuser@localhost>
Date: Thu, 23 Nov 2006 10:11:59 +0800 (GMT+08:00)
From: <from id>
To: <to id>
Subject: Product costs and Prices
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----=_Part_1_2028079228.1164247919089"
Return-Path: <from id>
X-OriginalArrivalTime: 23 Nov 2006 02:12:21.0138 (UTC) FILETIME=[CEDD3F20:01C70EA4]


---------------------------------------------------------

Any help on the same will be highly appreciated.

Thanks and regards,
Mandeep



Mailing from Oracle 10g IDS

Arindam Mukherjee, December 01, 2006 - 6:07 am UTC

Sir,

The current setup is Oracle application server (10G) on Linux OS and Microsoft Exchange Is on Windows 2003 server. Application server configuration file is configured to point to the exchange server as an SMTP server. For any report (Oracle Reports - 10g IDS) when DESTYPE is MAIL and DESNAME as email address, works very well when email address is one of the addresses defined in local domain, but gives error when email address is not from the local domain. For example “hcl.in” is the local intranet domain. There is user with name Arindam Mukherjee in this domain. When I send mail to arindamm@hcl.in, it is sent successfully, but when I try to send to arindamkol@yahoo.co.in, I get an error.

Could you kindly help me have the solution?


Tom Kyte
December 01, 2006 - 6:49 am UTC

please use

a) support
b) the forums on otn.oracle.com

for this one, I haven't used those tools in a decade myself.

Arindam Mukherjee, December 04, 2006 - 3:38 am UTC

Sir,

 Could you kindly help me solve the following proble? I have already serched in Google but could not get any positive help. you are my last resort. Please help me on this following code.

Version details are as follows :

1> Application server : Oracle 10G Version 10.1.2.0.2

2> OS: Linux Red Hat Enterprise edition release 4.

BEGIN
  :ErrorStatus := SendMailJPkg.SendMail(
  SMTPServerName => '10.118.6.205',
  Sender    => 'deepakmc@hcl.in',
  Recipient => 'deepakmc@hcl.in',
  CcRecipient => '',
  BccRecipient => '',
  Subject   => 'This is the subject line: Test JavaMail',
  Body => 'This is the body: Hello, this is a test' ||
  SendMailJPkg.EOL || 'that spans 2 lines',
  ErrorMessage => :ErrorMessage,
  Attachments  => SendMailJPkg.ATTACHMENTS_LIST(
  'C:\temp\hira.log',
  'C:\temp\IMP_SAI.BAT'
  )
);
END;
/

PL/SQL procedure successfully completed.

SQL> print

ERRORMESSAGE

--------------------------------------------------------------------------------


ERRORSTATUS

-----------

          0


Now if I change "Recipient => 'cmdeepak@gmail.com'," i.e., outside of local Network, I am getting the following problem.

PL/SQL procedure successfully completed.

 

SQL> print

ERRORMESSAGE

--------------------------------------------------------------------------------
javax.mail.SendFailedException: Sending failed;

  nested exception is:

        javax.mail.SendFailedException: Invalid Addresses;

  nested exception is:

        javax.mail.SendFailedException: 550 5.7.1 Unable to relay for cmdeepak@gmail.com


javax.mail.SendFailedException: Invalid Addresses;

  nested exception is:

        javax.mail.SendFailedException: 550 5.7.1 Unable to relay for cmdeepak@gmail.com

ERRORSTATUS

-----------

          1


Please kindly help me have the solution. I am really in great problem in this issue. Looking forward to your caring support.



 

Tom Kyte
December 04, 2006 - 7:22 am UTC

talk to your network administrators, the smtp server you are connecting to is NOT allowed to send mail outside of your machine - this is done to prevent spammers from hijacking you.

You need to find out what your companies real smtp server is

can we detect for mail box full

rahul, December 05, 2006 - 2:25 am UTC

Hi Tom,

I was just wondering if using the error codes returned by utl_smtp can we find if the recepients mailbox is full.
Does the error code 552 means the same?

Thanks,
Rahul.

Tom Kyte
December 05, 2006 - 9:56 pm UTC

look up the specification for smtp?? we are just telling you what was returned, we don't make up the numbers - they are told to us.

BCC name

Parag J Patankar, December 05, 2006 - 11:16 pm UTC

Hi Tom,

Thanks for your excellent PL/SQL script for sending email. I have tried to send email with BCC option, it works fine. But I have noticed that person in mailing list of BCC receives mail, but he can not see his address in BCC.

Can you show me how to do this changes ? This query I am asking you because of academic intrest.

thanks & regards
PJP

Tom Kyte
December 06, 2006 - 9:37 am UTC

that is the point of bcc, to NOT see the address.

BCC option

Parag J Patankar, December 06, 2006 - 11:32 pm UTC

Hi Tom,

Thanks for your answer regarding BCC. But If send mail thru Lotus Notes, to myself with BCC option, I can see only my address at BCC. Can you show me how to do this change in your Oracle Code ?

thanks & regards
PJP

Tom Kyte
December 07, 2006 - 9:46 am UTC

nope, because BCC should not be seen - this has NOTHING to do with the Oracle code - this is "smtp" and the email client.

Is it an error or warning?

Sumanth, February 08, 2007 - 9:43 am UTC

Hi Tom,

First of all thanks to you for this excellent resource

I have followed you steps in creating java source


SQL>set define off


  1  create or replace and compile java source named mymail
  2  as
  3      import java.io.*;
  4      import java.sql.*;
  5      import java.util.Properties;
  6      import java.util.Date;
  7      import javax.activation.*;
  8      import javax.mail.*;
  9      import javax.mail.internet.*;
 10      import oracle.jdbc.driver.*;
 11      import oracle.sql.*;
 12  public class mymail
 13     {
 14      static String dftMime = "application/octet-stream";
 15      static String dftName = "filename.dat";
 16      public static oracle.sql.NUMBER
 17                           send(String from,
 18                                String to,
 19                                String cc,
 20                                String bcc,
 21                                String subject,
 22                                String body,
 23                                String SMTPHost,
 24                                oracle.sql.BLOB attachmentData,
 25                                String attachmentType,
 26                                String attachmentFileName)
 27  {
 28        int rc = 0;
 29        try
 30        {
 31          Properties props = System.getProperties();
 32          props.put("mail.smtp.host", SMTPHost);
 33          Message msg=new MimeMessage(Session.getDefaultInstance(props, null));
 34          msg.setFrom(new InternetAddress(from));
 35          if (to != null && to.length() > 0)
 36            msg.setRecipients(Message.RecipientType.TO,InternetAddress.parse(to, false));
 37         if (cc != null && cc.length() > 0)
 38            msg.setRecipients(Message.RecipientType.CC,InternetAddress.parse(cc, false));
 39         if (bcc != null && bcc.length() > 0)
 40            msg.setRecipients(Message.RecipientType.BCC,InternetAddress.parse(bcc, false));
 41         if ( subject != null && subject.length() > 0 )
 42              msg.setSubject(subject);
 43         else msg.setSubject("(no subject)");
 44          msg.setSentDate(new Date());
 45          if (attachmentData != null)
 46          {
 47            MimeBodyPart mbp1 = new MimeBodyPart();
 48            mbp1.setText((body != null ? body : ""));
 49            mbp1.setDisposition(Part.INLINE);
 50            MimeBodyPart mbp2 = new MimeBodyPart();
 51            String type =
 52                (attachmentType != null ? attachmentType : dftMime);
 53            String fileName = (attachmentFileName != null ?
 54                               attachmentFileName : dftName);
 55            mbp2.setDisposition(Part.ATTACHMENT);
 56            mbp2.setFileName(fileName);
 57            mbp2.setDataHandler(new
 58               DataHandler(new BLOBDataSource(attachmentData, type))
 59            );
 60            MimeMultipart mp = new MimeMultipart();
 61            mp.addBodyPart(mbp1);
 62            mp.addBodyPart(mbp2);
 63            msg.setContent(mp);
 64          }
 65          else
 66          {
 67            msg.setText((body != null ? body : ""));
 68          }
 69          Transport.send(msg);
 70          rc = 1;
 71        } catch (Exception e)
 72        {
 73          e.printStackTrace();
 74          rc = 0;
 75        } finally
 76        {
 77          return new oracle.sql.NUMBER(rc);
 78        }
 79      }
 80      static class BLOBDataSource implements DataSource
 81      {
 82        private BLOB   data;
 83        private String type;
 84        BLOBDataSource(BLOB data, String type)
 85        {
 86            this.type = type;
 87            this.data = data;
 88        }
 89        public InputStream getInputStream() throws IOException
 90        {
 91          try
 92          {
 93            if(data == null)
 94              throw new IOException("No data.");
 95            return data.getBinaryStream();
 96          } catch(SQLException e)
 97          {
 98            throw new
 99            IOException("Cannot get binary input stream from BLOB.");
100          }
101        }
102        public OutputStream getOutputStream() throws IOException
103        {
104          throw new IOException("Cannot do this.");
105        }
106        public String getContentType()
107        {
108          return type;
109        }
110        public String getName()
111        {
112          return "BLOBDataSource";
113        }
114      }
115*   }
116  /

Operation 160 succeeded.

SQL>
SQL>



what is this "Operation 160 succeeded." mean?
Tom Kyte
February 08, 2007 - 11:18 am UTC

it means you have a really old release of sqlplus you are using against a newer release of the database.

Possible to remove Message-Id: <blah blah> from message?

Paul Vanover, March 07, 2007 - 10:51 am UTC

Your examples are excellent. I just had one follow-on question. When I send a message, somewhere in the message (seems to vary) I get this:

Message-Id: <iss.798ba011.7dd7.45eed9b7.9fb19.ca@cpmx.mail.saic.com>

It is embedded within the message and it isn't exactly in a great place. In my latest example, it gets embedded after the first line of the message. It seems like it would be at the end or something.

Anyway, I was just wondering if there is any way to make that go away, or at least make it appear where I want it to appear in my message? Thanks so much for your help.
Tom Kyte
March 07, 2007 - 11:10 am UTC

we don't put that there, not from "us"

if your smtp server is putting it in the wrong place (that belongs in the header, should not be visible in the message itself), then there is something wrong with your smtp server.

Thanks for responding, I think I figured it out.

Paul VanOver, March 07, 2007 - 12:06 pm UTC

I think I figured out the problem. When you said it belonged in the header, you were right, of course.

I added this:
  -- Last header block.
  UTL_SMTP.write_data(l_mail_conn, UTL_TCP.CRLF || UTL_TCP.CRLF);


to my pl/sql and the problem went away. It was like I needed to take up an additional line in the header before starting my message text, or something like that. This is all new to me. Anyway, I included a snippet of how it is now and it is working perfect. It doesn't include the line I mentioned in my last message.

Thanks so much again for your help!

Paul
  UTL_SMTP.open_data(l_mail_conn);
  
  UTL_SMTP.write_data(l_mail_conn, 'From: ' || pFromEmailAddr || UTL_TCP.CRLF);
  UTL_SMTP.write_data(l_mail_conn, 'To: ' || pToEmailAddr || UTL_TCP.CRLF);
  UTL_SMTP.write_data(l_mail_conn, 'Subject: ' || pSubject || UTL_TCP.CRLF);

  -- Last header block.
  UTL_SMTP.write_data(l_mail_conn, UTL_TCP.CRLF || UTL_TCP.CRLF);

  UTL_SMTP.write_data(l_mail_conn, pMessage);

  UTL_SMTP.close_data(l_mail_conn);
 
  UTL_SMTP.quit(l_mail_conn);

Time Zone issue?

Paul VanOver, March 08, 2007 - 4:22 pm UTC

Using the techniques described in this topic, I have created a nice little utility package in Oracle for sending email messages. I have resolved all the issues I was having, except for one.

Here is a code snippet:

    g_mail_conn := UTL_SMTP.open_connection(pMailHost, 25);
    UTL_SMTP.helo(g_mail_conn, pMailHost);
    UTL_SMTP.mail(g_mail_conn, pFromEmailAddr);

    l_to_list := LoadEmailList('To: ', pToEmailAddr);
    l_cc_list := LoadEmailList('Cc: ', pCCEmailAddr);

 
    UTL_SMTP.open_data(g_mail_conn);
  
    UTL_SMTP.write_data(g_mail_conn, 'Date: ' || to_char(systimestamp, 'dd Mon yy hh24:mi:ss tzh:tzm') || UTL_TCP.CRLF);
    UTL_SMTP.write_data(g_mail_conn, 'From: ' || nvl(pFromEmailAddr,'unknown@unknown.com') || UTL_TCP.CRLF);
    UTL_SMTP.write_data(g_mail_conn, 'Subject: ' || nvl(pSubject,'(NO SUBJECT)') || UTL_TCP.CRLF);


If you will notice I am using systimestamp and I have added the tzh:tzm to the format string and it returns the -5:00 for my time zone quite nicely. I am hoping this resolves all my time zone issues.

When I get messages that are sent from my oracle package, there is only one thing I don't know how to resolve. The Received Date on the message is perfect, but if I modify Microsoft Outlook, and add the Sent column to the email view, the times are wrong on those messages. They are 5 hours off. Is there some other attribute in the header I was suppose to set???

The data looks like this in Outlook:

From                 Subject   Received          Sent
vanoverp@saic.com    test      3/8/07 3:34 PM    3/8/07 10:34 AM


Thanks so much for any guidance you may provide.

Paul
Tom Kyte
March 08, 2007 - 8:38 pm UTC

you'd have to ask "outlook" what they are looking at.

not sure what they expect there.

oops, I did it again.

Paul VanOver, March 08, 2007 - 5:25 pm UTC

I figured it out. I had a mistake in the format in the to_CHAR method.

I changed it to
to_char(systimestamp, 'dd Mon yy hh24:mi:ss tzhtzm')


and life is all good now. YES YES YES>..

Thanks so much for all these awesome examples.

paul

sending attachements

Tomasz G., March 12, 2007 - 10:38 am UTC

Hi Tom,

Is there a way to send email with attachement from oracle by not using java solution (class and procedure send_mail) ?

I'm using oracle Xe and I cannot apply java solution for this.. maybe there is some other solution

Regards Tomasz
Tom Kyte
March 12, 2007 - 9:07 pm UTC

utl_mail

sending attachements

Tomasz G., March 14, 2007 - 6:00 am UTC

Yes but utl_mail is for smtp servers without autentication mode. I have server with autentication, oracle XE and I need to send email with attachements... is it possible?

Regards Tomasz
Tom Kyte
March 14, 2007 - 8:03 am UTC

sure, you just have to encode it yourself.

eg: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1739411218448

the way tyler sent HTML as an attachment in that example

sending attachements

Tomasz G., March 19, 2007 - 8:53 pm UTC

Ok finally I've got it. The secret was in MIME headers and boundaries. Now I can create emails with attachements (all types) where I want.

Thank you for help

mail

sam, March 27, 2007 - 3:19 pm UTC

Tom:

I have an application that send an email via a trigger after a user creates an order. IN the last month, some emails have not been going through. I check my email table and there is a record but emails were not received.

DO you have an idea what might be causing this and whehter it is realted to 9iR2 patch for timezone thing.

I tested it in SQl*plus and sometimes I received and email and sometimes I do not.

declare
begin
mail_pkg.send(p_sender_email=>'my_email@system.com',
p_from=>null,
p_to=>mail_pkg.array('my_email@system.com'),
p_cc=>mail_pkg.array(),
p_bcc=>mail_pkg.array('my_email@system'),
p_subject => 'ORder Confirm',
p_body => 'test1'||Chr(10)||'test2');
end;
Tom Kyte
March 28, 2007 - 11:17 am UTC

you should never ever send email in a trigger.

http://asktom.oracle.com/Misc/something-different-part-i-of-iii.html
http://asktom.oracle.com/Misc/part-ii-seeing-restart.html
http://asktom.oracle.com/Misc/part-iii-why-is-restart-important-to.html

however, if you run that plsql block and it returns without error, and you sometimes do not get the email - the problem is NOT in the database.

look to your email system, your SMTP server. it is broken.

email

sam, March 29, 2007 - 11:26 am UTC

Tom:

THe tirgger always worked but it seemed something is in the smtp server

ORA-12012: error on auto execute of job 23716
ORA-29278: SMTP transient error: 451 4.3.2 Please try again later
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 221
ORA-06512: at "XXX.MAIL_PKG", line 61
ORA-06512: at "XXX.SEND_EMAIL", line 37
ORA-06512: at line 1


I just ran this job and it worked. WHat do you think might be going in the smtp server that causes this?
Tom Kyte
March 30, 2007 - 12:55 pm UTC

I'd ask the owner of said SMTP server

probably - overloaded or file system full.

send email to smtpout.secureserver.net

Razaul Karim, April 03, 2007 - 12:29 am UTC

Mr. Tom,

I have followed UTL_SMTP accordingly for sending email from Developer 6i Forms. It is working well last 1 year when our smtp server was vmail2.bdcom.com. Presently we are using godaddy mail server (smtpout.secureserver.net). When I am sending a mail from Dev 6i the system is giving following error message.

ORA-29279

I am using the following Code:
create or replace package mail_pkg
as
type array is table of varchar2(255);

procedure send( p_sender_email in varchar2,
p_from in varchar2,
p_to in array default array(),
p_cc in array default array(),
p_bcc in array default array(),
p_subject in varchar2,
p_body in long );
end;
/


create or replace package body mail_pkg
as

g_crlf char(2) default chr(13)||chr(10);
g_mail_conn utl_smtp.connection;
-- g_mailhost varchar2(255) := 'vmail2.bdcom.com'; -- Host name of Mail Server (bdcom).
g_mailhost varchar2(255) := 'smtpout.secureserver.net'; -- Host name of Mail Server (bdcom). mail.bdbiz.net


function address_email( p_string in varchar2,
p_recipients in array ) return varchar2
is
l_recipients long;
begin
for i in 1 .. p_recipients.count
loop
utl_smtp.rcpt(g_mail_conn, p_recipients(i) );
if ( l_recipients is null ) then
l_recipients := p_string || p_recipients(i) ;
else
l_recipients := l_recipients || ', ' || p_recipients(i);
end if;
end loop;
return l_recipients;
end;


procedure send( p_sender_email in varchar2,
p_from in varchar2,
p_to in array default array(),
p_cc in array default array(),
p_bcc in array default array(),
p_subject in varchar2,
p_body in long)
is
l_to_list long;
l_cc_list long;
l_bcc_list long;
l_date varchar2(255) default
to_char( SYSDATE, 'dd Mon yy hh24:mi:ss' );

procedure writeData( p_text in varchar2 )
as
begin
if ( p_text is not null ) then
utl_smtp.write_data( g_mail_conn, p_text || g_crlf );
end if;
end;


begin
g_mail_conn := utl_smtp.open_connection(g_mailhost, 25);

utl_smtp.helo(g_mail_conn, g_mailhost);
utl_smtp.mail(g_mail_conn, p_sender_email);

l_to_list := address_email( 'To: ', p_to );
l_cc_list := address_email( 'Cc: ', p_cc );
l_bcc_list := address_email( 'Bcc: ', p_bcc );

utl_smtp.open_data(g_mail_conn );

writeData( 'Date: ' || l_date );
writeData( 'From: ' || nvl( p_from, p_sender_email ) );
writeData( 'Subject: ' || nvl( p_subject, '(no subject)' ) );

writeData( l_to_list );
writeData( l_cc_list );

utl_smtp.write_data( g_mail_conn, '' || g_crlf );
utl_smtp.write_data(g_mail_conn, p_body );
utl_smtp.close_data(g_mail_conn );
utl_smtp.quit(g_mail_conn);
end;
end;
/


Please give me a solution, I will be very grateful to you.


Tom Kyte
April 03, 2007 - 11:06 pm UTC

use telnet, telnet to the server and just converse with it.

take oracle out of the loop, you'll see the error lies with your conversation with the smtp server.


IOException while sending message

Anderson Onir, April 04, 2007 - 1:27 pm UTC

TOM

We are using a solution based in this answer on Oracle DB version 10.1.0.3 for years, but now we upgrade to version 10.2.0.3 and i receive this exception:
javax.mail.MessagingException: IOException while sending message;
  nested exception is:
 java.io.IOException: Cannot get binary input stream from BLOB.
 at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:625)
 at javax.mail.Transport.send0(Transport.java:169)
 at javax.mail.Transport.send(Transport.java:98)
 at mailX.send(mailX:221)
Caused by: java.io.IOException: Cannot get binary input stream from BLOB.
 at mailX$BLOBDataSource.getInputStream(mailX:263)
 at javax.activation.DataHandler.writeTo(DataHandler.java:304)
 at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
 at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:845)
 at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:361)
 at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:85)
 at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:883)
 at javax.activation.DataHandler.writeTo(DataHandler.java:316)
 at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350)
 at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1683)
 at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:585)
 ... 3 more



my code is:
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "mailX"
AS import java.io.*;
import java.sql.*;
import java.util.Properties;
import java.util.Date;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;



public class mailX
{
  static String dftMime = "application/octet-stream";
  static String dftName = "filename.dat";

  public static oracle.sql.NUMBER
                       send(String from,
                            String to,
                            String cc,
                            String bcc,
                            String subject,
                            String body,
                            String SMTPHost,
                            boolean multiAttachment,
                            boolean notification)
  {
    int rc = 0;
    OracleConnection connection = null;      // Database Connection Object

    try
    {
      Properties props = System.getProperties();
      props.put("mail.smtp.host", SMTPHost);
      Message msg =
        new MimeMessage(Session.getDefaultInstance(props, null));

     msg.setFrom(new InternetAddress(from));
     if (notification)
     {
        msg.setHeader("X-Confirm-Reading-To", from);
        msg.setHeader("Disposition-Notification-To", from);
     }

     if (to != null && to.length() > 0)
        msg.setRecipients(Message.RecipientType.TO,
                          InternetAddress.parse(to, false));

     if (cc != null && cc.length() > 0)
        msg.setRecipients(Message.RecipientType.CC,
                          InternetAddress.parse(cc, false));

     if (bcc != null && bcc.length() > 0)
        msg.setRecipients(Message.RecipientType.BCC,
                          InternetAddress.parse(bcc, false));

     if ( subject != null && subject.length() > 0 )
          msg.setSubject(subject);
     else msg.setSubject("(sem assunto)");

      msg.setSentDate(new Date());

      if (multiAttachment)
      {
        MimeBodyPart mbp1 = new MimeBodyPart();
        mbp1.setText((body != null ? body : ""));
        mbp1.setDisposition(Part.INLINE);

        MimeMultipart mp = new MimeMultipart();
        mp.addBodyPart(mbp1);

        String type = dftMime;

      try {
        int rowFetched = 0;

        connection = (OracleConnection)new oracle.jdbc.driver.OracleDriver().defaultConnection();
        OraclePreparedStatement stmt = (OraclePreparedStatement)connection.prepareStatement
                                ("SELECT ds_nome, conteudo " +
                                 "  FROM hw_temp_anexos    " );

        OracleResultSet rset = (OracleResultSet)stmt.executeQuery();
// Execute query and get Resultset

        oracle.sql.BLOB b;

        // Loop through Result Set and fetch the result
        while (rset.next()) {
          MimeBodyPart mbp2 = new MimeBodyPart();

          rowFetched ++;

          String fileName = rset.getString("ds_nome"); // Fetch ds_nome

          mbp2.setDisposition(Part.ATTACHMENT);
          mbp2.setFileName(fileName);

          b = rset.getBLOB("conteudo");

          mbp2.setDataHandler(new
             OracleDataHandler(new BLOBDataSource(b, type))
          );

          mp.addBodyPart(mbp2);
        }

        // Close the Resultset and statement object
        rset.close();
        stmt.close();
        msg.setContent(mp);

      } catch (SQLException ex) { // Trap SQL Errors
        ex.printStackTrace();

      } finally {
         try{
           if (connection != null || !connection.isClosed())
               connection.close();   // Close the database connection
           } catch(SQLException ex){
             ex.printStackTrace();
           }
        }

      }
      else
      {
        msg.setText((body != null ? body : ""));
      }
      Transport.send(msg);
      rc = 1;
    } catch (Exception e)
    {
      e.printStackTrace();
    }
    return new oracle.sql.NUMBER(rc);
  }


  // Nested class that implements a DataSource.

  static class BLOBDataSource implements OracleDataSource
  //DataSource
  {
    private oracle.sql.BLOB data;
    private String type;

    BLOBDataSource(oracle.sql.BLOB data, String type)
    {
        this.type = type;
        this.data = data;
    }

    public InputStream getInputStream() throws IOException
    {
      try
      {
        if(data == null)
          throw new IOException("No data.");

        return data.getBinaryStream();
      } catch(SQLException e)
      {
        throw new
        IOException("Cannot get binary input stream from BLOB.");
      }
    }

    public OutputStream getOutputStream() throws IOException
    {
      throw new IOException("Cannot do this.");
    }

    public String getContentType()
    {
      return type;
    }

    public String getName()
    {
      return "BLOBDataSource";
    }
  }

}
/


DESC hw_temp_anexos;

Describing hw_temp_anexos....
NAME                            Null?     Type
------------------------------- --------- -----
TEA_ID                                    NUMBER
CONTEUDO                                  BLOB(4000)
TEA_OSUSER                                VARCHAR2(30)
TEA_USER                                  VARCHAR2(30)
STAMP                                     DATE
DS_NOME                                   VARCHAR2(256)
NR_IP_HOST                                VARCHAR2(40)
NR_IP_NET                                 VARCHAR2(40)
DT_INSERT                                 DATE
NO_USER_INSERT                            VARCHAR2(30)



What may be causing this IOException?

Tom Kyte
April 04, 2007 - 3:42 pm UTC

debug it - whittle it down, make it small, get the least amount of code humanly possible to reproduce your issue

and the problem may well become self evident.

IOException while sending message

Anderson Onir, April 04, 2007 - 1:50 pm UTC

My code on last review are incorrect...

The correct is this:

CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "mailX"
AS import java.io.*;
import java.sql.*;
import java.util.Properties;
import java.util.Date;
import javax.activation.*;
import javax.mail.*;
import javax.mail.internet.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;



public class mailX
{
  static String dftMime = "application/octet-stream";
  static String dftName = "filename.dat";

  public static oracle.sql.NUMBER
                       send(String from,
                            String to,
                            String cc,
                            String bcc,
                            String subject,
                            String body,
                            String SMTPHost,
                            boolean multiAttachment,
                            boolean notification)
  {
    int rc = 0;
    OracleConnection connection = null;      // Database Connection Object

    try
    {
      Properties props = System.getProperties();
      props.put("mail.smtp.host", SMTPHost);
      Message msg =
        new MimeMessage(Session.getDefaultInstance(props, null));

     msg.setFrom(new InternetAddress(from));
     if (notification)
     {
        msg.setHeader("X-Confirm-Reading-To", from);
        msg.setHeader("Disposition-Notification-To", from);
     }

     if (to != null && to.length() > 0)
        msg.setRecipients(Message.RecipientType.TO,
                          InternetAddress.parse(to, false));

     if (cc != null && cc.length() > 0)
        msg.setRecipients(Message.RecipientType.CC,
                          InternetAddress.parse(cc, false));

     if (bcc != null && bcc.length() > 0)
        msg.setRecipients(Message.RecipientType.BCC,
                          InternetAddress.parse(bcc, false));

     if ( subject != null && subject.length() > 0 )
          msg.setSubject(subject);
     else msg.setSubject("(sem assunto)");

      msg.setSentDate(new Date());

      if (multiAttachment)
      {
        MimeBodyPart mbp1 = new MimeBodyPart();
        mbp1.setText((body != null ? body : ""));
        mbp1.setDisposition(Part.INLINE);

        MimeMultipart mp = new MimeMultipart();
        mp.addBodyPart(mbp1);

        String type = dftMime;

      try {
        int rowFetched = 0;

        connection = (OracleConnection)new oracle.jdbc.driver.OracleDriver().defaultConnection();
        OraclePreparedStatement stmt = (OraclePreparedStatement)connection.prepareStatement
                                ("SELECT ds_nome, conteudo " +
                                 "  FROM hw_temp_anexos    " );

        OracleResultSet rset = (OracleResultSet)stmt.executeQuery();
// Execute query and get Resultset

        oracle.sql.BLOB b;

        // Loop through Result Set and fetch the result
        while (rset.next()) {
          MimeBodyPart mbp2 = new MimeBodyPart();

          rowFetched ++;

          String fileName = rset.getString("ds_nome"); // Fetch ds_nome

          mbp2.setDisposition(Part.ATTACHMENT);
          mbp2.setFileName(fileName);

          b = rset.getBLOB("conteudo");

          mbp2.setDataHandler(new
             DataHandler(new BLOBDataSource(b, type))
          );

          mp.addBodyPart(mbp2);
        }

        // Close the Resultset and statement object
        rset.close();
        stmt.close();
        msg.setContent(mp);

      } catch (SQLException ex) { // Trap SQL Errors
        ex.printStackTrace();

      } finally {
         try{
           if (connection != null || !connection.isClosed())
               connection.close();   // Close the database connection
           } catch(SQLException ex){
             ex.printStackTrace();
           }
        }

      }
      else
      {
        msg.setText((body != null ? body : ""));
      }
      Transport.send(msg);
      rc = 1;
    } catch (Exception e)
    {
      e.printStackTrace();
    }
    return new oracle.sql.NUMBER(rc);
  }


  // Nested class that implements a DataSource.

  static class BLOBDataSource implements DataSource
  {
    private oracle.sql.BLOB data;
    private String type;

    BLOBDataSource(oracle.sql.BLOB data, String type)
    {
        this.type = type;
        this.data = data;
    }

    public InputStream getInputStream() throws IOException
    {
      try
      {
        if(data == null)
          throw new IOException("No data.");

        return data.getBinaryStream();
      } catch(SQLException e)
      {
        throw new
        IOException("Cannot get binary input stream from BLOB.");
      }
    }

    public OutputStream getOutputStream() throws IOException
    {
      throw new IOException("Cannot do this.");
    }

    public String getContentType()
    {
      return type;
    }

    public String getName()
    {
      return "BLOBDataSource";
    }
  }

}
/


PL/SQL - Email

Rajesh Shridharan, April 23, 2007 - 5:44 am UTC

Hi Tom,

I am trying to implement Email solution through PL/SQL using Oracle 9i. I want to send the Email to id in yahoo / rediffmail, However I am getting error :

ORA-29279: SMTP permanent error: 553 sorry, that domain isn't in my list of
allowed rcpthosts (#5.7.1)


Can you please explain how can I can implement this?

Regards

Rajesh Shridharan

Tom Kyte
April 23, 2007 - 4:33 pm UTC

see your network people and ask them to add you to the list of domains that are allowed rcpthosts....

nothing to do with the database
everything to do with your smtp server.

smtp server

A reader, May 01, 2007 - 5:08 pm UTC

Tom:

I checked with the email server admin about the email problems from an oracle application (emails not getting sent out or even received by email server) and he suggested to install an smtp server on the box where the database is installed or have the oracle application do queueing for the busy smtp server as it gets backed out sometimes?

1. How do you install/configure an smtp server on a unix box running oracle? can this be done?

2. Does MAIL_PKG in oracle suport queueing. Since we are using a job to schedule the email, is not this queueing since if the job fails (server down) oracle will try to send the job 14 times in 5 minute intervals?

Thanks,
Tom Kyte
May 01, 2007 - 9:04 pm UTC

1) your email server admin would know how to do that - it is just smtp, a simple service.

2) Oracle supports job queueing, you would have a job that tries to send mail and upon failure, would just try again later.

you could use dbms_job
you could use dbms_scheduler
you could use AQ and do it yourself in however you see fit.

java.security.AccessControlException error

Anne, June 04, 2007 - 2:15 pm UTC

I have 2 schema's in a 9.2.0.4 database : bps and mr_proj. Package SendMailJPkg is compiled in bps schema as authid CURRENT_USER. Sending email with attachment works from from bps schema. My problem is when I send email with attachement by running bps.SendMailJPkg from mr_proj schema : I get java.security.AccessControlException error. Ending email without attachment works fine from mr_proj. I am not sure what I am doing wrong...Could you please help.

This are the steps I followed:
1. In bps schema : create public synonym SendMailJPkg for bps.SendMailJPkg;

2. grant execute on SendMailJPkg to mr_proj;

 exec dbms_java.grant_permission( 'MR_PROJ', 'SYS:java.util.PropertyPermission', '*', 'read,write' )

 exec dbms_java.grant_permission( 'MR_PROJ', 'SYS:java.net.SocketPermission', 'smtp.dnr.state.mn.us', 'resolve' )

exec dbms_java.grant_permission('MR_PROJ', 'SYS:java.io.FilePermission', '/r03/app/oracle/admin/mris/mr_proj/log/*','read');

PL/SQL procedure successfully completed.

commit;

3. Log out and login as mr_proj

Here is the script test_sendmail.sql :
--Simple test 
var ErrorMessage VARCHAR2(4000);  
var ErrorStatus NUMBER;

-- enable SQL*PLUS output;
SET SERVEROUTPUT ON size 1000000
-- redirect java output into SQL*PLUS buffer;
exec dbms_java.set_output(5000);
declare
   --bps@mristest
   --g_dir varchar2(1000) :=  '/r03/app/oracle/admin/mris/bps/log';
   --g_file varchar2(1000) :=  'psb75.req';

   --mr_proj@mristest
   g_dir varchar2(1000) :=  '/r03/app/oracle/admin/mris/mr_proj/log';
   g_file varchar2(1000) :=  'abj.req';


BEGIN
   :ErrorStatus := SendMailJPkg.SendMail(
                SMTPServerName => 'smtp.dnr.state.mn.us',
                Sender    => 'oracle@pinky.dnr.state.mn.us',
                Recipient => 'bella.joseph@dnr.state.mn.us',
                Subject   => 'This is the subject line: Test JavaMail  Attachments',
                Body => 'This is the body: Hello, this is a test' ||
                         SendMailJPkg.EOL || 'that spans 2 lines',
                ErrorMessage => :ErrorMessage,
                Attachments  => SendMailJPkg.ATTACHMENTS_LIST(g_dir || '/' || g_file  )
   );
END;
/
print


mr_proj@mris> @test_sendmail;

PL/SQL procedure successfully completed.

ERROR at line 1:
ORA-29532: Java call terminated by uncaught Java exception: java.security.AccessControlException: the Permission (java.io.FilePermission /r03/app/oracle/admin/mris/mr_proj/log/abj.req read) has not been granted to BPS. The PL/SQL to grant this is dbms_java.grant_permission( 'BPS', 'SYS:java.io.FilePermission', '/r03/app/oracle/admin/mris/mr_proj/log/abj.req', 'read' )

It is complaining that the permission is not given to BPS. However I do not want BPS to be able to access mr_proj's log dir, that's kind of why I defined the SendMailJPkg as authid CURRENT_USER. 



Appreciate your help Tom.

Tom Kyte
June 06, 2007 - 12:24 pm UTC

it'll need it - you eventually call other non-current user bits of Oracle.

the plsql/java called by compiled plsql is compiled/linked with the definer - (eg:

you can create an authid current_user procedure 'p' OWNED BY 'owner', to be run by 'runner'

owner has been granted execute on P2
runner has not

P compiled by OWNER can invoked P2
when P is executed by RUNNER - P will invoked P2 successfully.


It is "SQL" that is invokers rights capable.

Can't send mail using UTL_SMTP

Sukhendu, June 22, 2007 - 6:11 am UTC

Hi Tom,

When I am trying to send a simple mail through pl/sql using oracle 9.1 . It throws the following error:

ORA-04067: not executed, package body "ME.UTL_SMTP" does not exist
ORA-06508: PL/SQL: could not find program unit being called: "ME.UTL_SMTP"

What should I have to do to send the mail. Please suggest.

Thanks,
Sukhendu
Tom Kyte
June 22, 2007 - 10:29 am UTC

utl_smtp is a sys owned package, sort of like dbms_output, and the rest.

whatever "ME" is is wrong.


unable to configure utl_smtp

Chitta, July 25, 2007 - 1:51 pm UTC

Hi Tom,
I am using 9.2.0.7.0 database and try to configure automatic mail from database to my personal ID. presently i am getting mail from Application now my requirment is from database.
but i got error like:
ERROR at line 1:
ORA-29278: SMTP transient error: 421 Service not available
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 138
ORA-06512: at "MAAEC.SEND_TO_NA_MAAEC", line 9
ORA-06512: at "MAAEC.SERVER_ID_CHECK", line 25
ORA-04088: error during execution of trigger 'MAAEC.SERVER_ID_CHECK'


i had checked with SA that the SMTP was configured properly.
please advice where i need to look in?

Thanks in Advance,
Chitta

Tom Kyte
July 26, 2007 - 5:40 pm UTC

no, it isn't.

or you are using the wrong smtp server.


test by ctl-f'ing for

remove utl_smtp from the loop, test with telnet:

on this page.

sending e-mails

A reader, October 02, 2007 - 11:39 am UTC

Tom,

I created send_mail procedure (in 10.2) as following:

create or replace PROCEDURE send_mail (      p_sender IN VARCHAR2,
                           p_recipient IN VARCHAR2,
                           p_message IN VARCHAR2)
AS
    mailhost    VARCHAR2(255) := '***.com';
    mail_conn  utl_smtp.connection;
BEGIN
    mail_conn := utl_smtp.open_connection(mailhost, 25);
    utl_smtp.helo(mail_conn, mailhost);
    utl_smtp.mail(mail_conn, p_sender);
    utl_smtp.rcpt(mail_conn, p_recipient);
-- If we had the message in a single string, we could collapse
-- open_data(), write_data(), and close_data() into a single call to data()
    utl_smtp.open_data(mail_conn);
    utl_smtp.write_data(mail_conn, p_message);
    utl_smtp.close_data(mail_conn);
    utl_smtp.quit(mail_conn);
END;

and execute it by

SQL> exec send_mail(p_sender=>'*.com', p_recipient=>'*.com', p_message=>'Test');

PL/SQL-Prozedur erfolgreich abgeschlossen.

What I received is a mail with a zero body (p_message string is ignored)

I spent two hours trying to find an error...What I did wrong? It is the same code as in your book.

Tom Kyte
October 05, 2007 - 10:57 am UTC

I see you have a language other than english set there, are you sure your email body is simple ASCII text (smtp expects that)

that works (the routine), works for me - you can do it all in telnet without Oracle if you want to test and see what you see there.

ctl-f for

test with telnet

on this page for an example

Reader

Pat, December 17, 2007 - 1:09 pm UTC

In 9i I was sucessfully able to send email with attachments. Now my requirement is to save the sent email in the database for audit purpose. Can you please explain options?
Tom Kyte
December 17, 2007 - 3:25 pm UTC

option 1:

a) insert


??? seems rather straightforward, relational databases have tables, insert your stuff into a table.

Just like any other data you have a requirement to keep.

Pat, December 21, 2007 - 3:36 pm UTC

Thanks for your response Tom.
I have a requirement to save as how the email show if we do a save as,I have to save with all the header info.
1)Is there any way we can recieve an email in the database, so that i can save the received email.
or
2)Is there any way we can direct the out of the sent email to save to a table.
Tom Kyte
December 21, 2007 - 4:04 pm UTC

java has lots of support for connecting to email data stores (IMAP, POP) and would give you the ability to "read the mail"

Just like I demonstrated above for sending - you can certainly do the same for reading.

But basically, you'll be writing a program to read email from an email server, format the data, and insert it into the database - not necessary to have the program that does that IN the database, probably doesn't make sense to have it in the database - sounds more like an external program that runs on it's own accord, reading mail, formatting it, inserting it.

Another option would be to use an email server that stored the data in the database in the first place - we have one (collaboration suite) for example.

Pat, December 21, 2007 - 4:27 pm UTC

Thanks Tom you are wonderful.

UTL_SMTP and Shared Server

Emad Kehail, January 05, 2008 - 3:04 am UTC

Hi Tom,

We have been using the package utl.smtp to send email in our database. We have built a package called DEMO_MAIL which uses the UTL_SMTP package. The code has run successfully for more than 3 years without any problem. Lately, we changed our server configuration from Dedicated server to Shared.
End users starts to report problems while our applications try to send emails
the error code was as follows:

ORA-29278: SMTP Transient error: 421 service not available
ORA-06512: at "SYS.UTL_SMTP", line 17
ORA-06512: at "SYS.UTL_SMTP", line 96
ORA-06512: at "SYS.UTL_SMTP", line 138
ORA-06512: at "ORAPROG.DEMO_MAIL", line 240
ORA-06512: at "ORAPROG.DEMO_MAIL", line 118
ORA-06512: at line 118

We have done the following tests:

* When connecting to the server using a didected connection there is no problem.
* When connecting to the server using a shared server the above error occurs and sometimes it works successfully!.

Moreover, when we execute it many times we start to receive the error:

ORA-30678 too many open connections

Despite our code close the session with mail server.

Is there any problem in using UTL_SMTP with Shared Server configuration in Oracle Database??


Thanks.

Tom Kyte
January 07, 2008 - 7:23 am UTC

you may contact support and reference bug 4083461 but....

one easy way to correct this AND have it be faster all around for your end user experience would be....

to use dbms_job to schedule the sending of the email. What I do on asktom is

a) insert the email information into a table (this is instantaneous for the end user)

b) commit my transaction.

Every 5 minutes or so, a job wakes up, queries the email table for unsent mail - sends it.


Sending Email

Rich Bulan, January 07, 2008 - 4:42 pm UTC

Tom,
We've successfully implemented email workflow via the database examples that you've provided. I would love to see some additional examples that utilize some of the advanced features of email.
*How to email messages (and subject lines) in non-ASCII character sets (French Canadian)?
*Examples for how bounce back emails are handled?
*Clear documentation on what really happens when we send emails via these procedures like utl_smtp or utl_mail. The information from documentation could really use some comprehensive examples:
http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/u_smtp.htm#sthref19034

Thanks!
Tom Kyte
January 07, 2008 - 5:35 pm UTC

You'd have to read up on the SMTP protocol itself - OR use the java api's - but that is outside the scope of a database question sort of- you want to learn SMTP.


for bounce backs, you'd have to write an email client that wakes up, reads the inbox, parses the email and figures out what it wants to do (it is just a data problem - think of the inbox you have your bounces go to as if it were a bunch of files, you can use pop or imap to read them - just like we use smtp to send them)

As for "what happens", you want to read the SMTP RFC - we just open a tcp/ip socket to a SMTP server and speak their documented protocol - ctl-f for telnet on this page and you'll see a rather "raw" conversation. There is on magic here, it is all just "smtp speak" - and that protocol is well documented (google it and you'll find a lot of references)

Sending emails from Shared Server

Emad Kehail, January 08, 2008 - 1:27 am UTC

Yes Tom, it seems it is a bug, and according to Metalink note 358776.1, patch 9.2.0.8 should solve it.

I will test it and see about it.

It is also solved in Oracle 10g R2. However, we are currently discussing upgrading to Oracle 10g R2 or Oracle 11g R1. I hope the patch solve our problem till we upgrade.

Thanks for your cooperation

Tom Kyte
January 08, 2008 - 7:33 am UTC

I would still use dbms_job

it'll make email "transactional", so if the surrounding transaction rolls back - so does the email. If you commit, the email will be sent. The end user transaction will go from taking measurable seconds to instantaneous.

No way we should send email in real time, background it regardless.

Sending emails from Shared Server

Emad Kehail, January 10, 2008 - 2:07 am UTC

We have applied patch 9.0.2.8 and everything is fine now.
Regarding your point about transactional emails. As always you were right here. I have talked to our developers. They are using Oracle Forms and they are sending emails either from POST-INSERT, POST-UPDATE, POST-DELETE or database triggers.
This could lead to problems if the form has executed the trigger and sent the email, then the database might rollback the transaction if a constraint is violated for example or anything else happened prevented the database from *committing* the transaction.

I do believe now we need to follow your idea about how we send emails.

Many thanks for your valuable hints.


Problems with loadjava

Natalia, February 06, 2008 - 2:03 pm UTC

Hi Tom. I'm trying to create the objects needed to send emails with attatchments. When i execute
loadjava -u sys/xxxx -o -r -v -f -noverify -synonym -g public mail.zip
I get many errors ORA-29521 and ORA-29534.
My database is 9.2.0.6
Please help me
Thanks in advance
PS: Sorry for my poor english!!!

Mail and attachment

Nilesh, February 22, 2008 - 7:02 am UTC

Hi Tom,

I have 2 different database, both have the same oracle version i.e. 9i. The above java mail package worked perfectly for one database and I was able to send mail with attachment.

For another DB when I am trying to create Java Class its give error of ORA-03113: end-of-file on communication channel and the DB get disconnected.

Please help me out.

Thanks in Advance
Tom Kyte
February 22, 2008 - 7:26 am UTC

ora-600
ora-7445
ora-3113

all mean "please utilize support"

email

A reader, March 22, 2008 - 9:26 pm UTC

Tom:

1. Is installing java api the only choice to send an email with an attachment in oracle 9i database?

2. Can the attachemnt work with any column type meaning if I have document_table with a blob i can select the file from that row. What about if i have a varchar2(2000) column would that be attached as I need to create a file first?

thanks,
Tom Kyte
March 24, 2008 - 11:16 am UTC

you have utl_smtp in 9i

http://docs.oracle.com/docs/cd/B10501_01/appdev.920/a96612/u_smtp.htm#1000695

and smtp is just a protocol, you would encode the attachments (using base64 or uuencode) and create a "correct and proper SMTP 'document'"

It requires more code than using something out of the box, but it can definitely be done. Tyler Muth did it with "html mail" here:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1739411218448

he did not have to encode the html attachment, as it was just ascii text, but the concept is the same

email

A reader, March 24, 2008 - 2:17 pm UTC

Tom:

It seems the java option is easier as you have all the code written for it.

With utl_smtp do I need to add more coding/testing or
the procedure html_email( ) will handle everything?

2. also, can attachements be any column type like "CLOB", "BLOB", varchar2(4000), etc.

Is there anything special that needs to be done for each type.

Thanks,


Tom Kyte
March 24, 2008 - 7:31 pm UTC

html_email will send.....

html, nothing more, nothing less. It was an example of what you would have to do...

2) using javamail - it won't matter, it will encode them, doing it YOURSELF, you would have to write different interfaces/implementations for each type of course.

email

A reader, March 24, 2008 - 2:29 pm UTC

Tom:

Another small question on utl_smtp. I already use that for plain text emails "no attachments". Does this mean that I already have the Jave code requried or do i still need to download those two files (mail.jar and activation.jar).

is there a way to check if those two file are already compiledi nto the database.

thanks,
Tom Kyte
March 24, 2008 - 7:32 pm UTC

read that html email answer again.

see what tyler did there with the "attachment" stuff.

that is what you would have to code, AFTER encoding documents using base64/uuencode

if base64/uuencode mean nothing to you - please use the javamail api :)

if that means something to you and you understand the attachments and how SMTP wants them and all - you'll be able to make the decision "build versus buy" here (write it or use the java mail API)


mail

A reader, March 24, 2008 - 3:22 pm UTC

Tom:

Per your instructions i downloaded "jaf-1_1_1.zip" and "javamail-1_4_1.zip" from the Sun website.

I extracted each file contents and did find mail.jar and activation.jar.

Then I got lost on your instructions. You say to

1. Use winzip to extract the contents of mail.jar into c:\temp\mail dierctory. There is no files inside this exectable file??

Did you mean something else?

2. Use winzip to create a new archive c:\temp\mail8i.zip.

Do you mean a new archive of the original files in "javamail-1_4_1.zip".

3. Put the contents of c:\temp\mail\*.8 including subdiretories into this new archive.

I thought you want us to extract the mail,jar only first. What are we zipping here exactly?

Thanks,

email

A reader, March 24, 2008 - 9:01 pm UTC

Tom:

Yes, I am not familiar with uuencode and base 64 encoding.

It seems the java api would be easier.

Can you just clarify the above steps on installing the two files.
Tom Kyte
March 25, 2008 - 6:32 am UTC

a jar file is a zip file - just unzip it.

jar file

A reader, March 25, 2008 - 6:10 pm UTC

Tom:

I tried this many times and it does not work. These are executable files.

I ran winzip and i opened javamail-1_4_1.zip. This zip file has two files "mail.jar" and "mailapi.jar".

These are defined as "Executable jar file". I selected the files and clicked "extract" but nothing is done. I do not think these have any files inside them.

So what do you do now. do you unjar and rejar those for compilation into the oracle database.
Tom Kyte
March 26, 2008 - 8:50 am UTC

you extract the jars.

please re-read the page....

.... quote ....
After you have downloaded these two sets of files ? you will need to extract
mail.jar from the JavaMail APIdownload and activation.jar from the JAF
download.
This is all you will need from this ? feel free to read through the
documentation, there is a lot of functionality in there we are not using, we
are just using the 'send an email' part of the API. The API includes functions
for receiving mail as well from IMAP, POP, and other sources.
.......

we need the jars from the zips

email

A reader, March 26, 2008 - 10:18 am UTC

Tom:

I did that. My question is regarding what you say next to unjar/rejar those. There is nothing to unzip in those executables.
----------------------------------------------------------
We will need to load the mail.jar and activation.jar into the database using loadjava but
before we can do that we must repackage them. These jar files are compressed in a format
that is not understood by the database byte code interpreter. You need to 'unjar' and
'rejar' them without compression or use a tool such as WinZip to 'rejar' them into a zip
file. What I did on Windows 2000 was:

1. Used WinZip to extract the contents of mail.jar into my c:\temp\mail directory
2. Used WinZip to create a new archive c:\temp\mail8i.zip
3. Put the contents of c:\temp\mail\*.* including subdirectories into this new archive
-------------------------------------------------------
Tom Kyte
March 26, 2008 - 10:29 am UTC

go ahead, open them with winzip, see what you see. a jar is just a zip.


a jar is a zip

just open it with WINZIP (i just did... a jar is a zip, a jar is not an "executable", it is just a big file with class files in it)

email

A reader, March 26, 2008 - 6:26 pm UTC

Tom:

You are 100% correct. Your instructions were valid and concise. I sent the two zip files to dba to compile using loadjava command.

Thank you,

loadjava

A reader, March 31, 2008 - 3:26 pm UTC

Tom:

Is not the "loadjava" a sql*plus command (or unix)?

SQL> loadjava -u my_account/my_account -o -r -v -f -noverify -synonym -g public c:\temp1\mail9i.zip;
SP2-0734: unknown command beginning "loadjava -..." - rest of line ignored.


2. 
if "my_account" has priviledges to run "Loadjava" would it work or it has to be run using SYS/MANAGER?

Tom Kyte
March 31, 2008 - 4:02 pm UTC

loadjava is an OS command.


$ which loadjava
/home/ora10gr2/bin/loadjava


you can use dbms_java.loadjava as well. A stored procedure, but then the file needs be on the server.

loadjava

A reader, March 31, 2008 - 4:18 pm UTC

Tom:

so i have to ftp files to server and either run unix "loadjava" in the oracle home directory or sql*plus "dbms_java.loadjava".

I can't use SQL*Plus on windows and compile from client like this?

SQL> exec dbms_java.loadjava -u sadmin/sadmin -o -r -v -f -noverify -synonym -g public c:\temp1\mail9i.zip;
BEGIN dbms_java.loadjava -u sadmin/sadmin -o -r -v -f -noverify -synonym -g public c:\temp1\mail9i.zip; END;

                         *
ERROR at line 1:
ORA-06550: line 1, column 26:
PLS-00103: Encountered the symbol "-" when expecting one of the following:
:= . ( @ % ;

Tom Kyte
March 31, 2008 - 4:46 pm UTC

no, you can use loadjava over a network - you just need to have it actually be installed.

you use dbms_java to load a jar file that is on the server already.



dbms_java is a store package, it runs in the server, it has absolutely ZERO access to your filesystem, it only has access to the server.

java error

A reader, April 02, 2008 - 12:09 pm UTC

Tom:

We ran the mail9i.zip first on ibm aix machine with ORacle 9.2.0.2. We got mainly two errors listed below. The list is 30 pages long and I only listed a few of those two errors. Do you know how to fix this issue?


/ora920/admin/macd/scripts/java> onym -g public mail9i.zip <
arguments: '-user' 'sys/macadmin as sysdba' '-o' '-r' '-v' '-f' '-noverify' '-sy
nonym' '-g' 'public' 'mail9i.zip'
creating : class com/sun/mail/handlers/image_gif
created : CREATE$JAVA$LOB$TABLE
loading : class com/sun/mail/handlers/image_gif
created : JAVA$CLASS$MD5$TABLE
creating : class com/sun/mail/handlers/image_jpeg
loading : class com/sun/mail/handlers/image_jpeg

....

granting : execute on class com/sun/mail/handlers/image_jpeg to public
resolving: class com/sun/mail/handlers/image_jpeg
synonym : com/sun/mail/handlers/image_jpeg
granting : execute on class com/sun/mail/handlers/message_rfc822 to public
resolving: class com/sun/mail/handlers/message_rfc822
errors : class com/sun/mail/handlers/message_rfc822
ORA-29534: referenced object SYS.javax/mail/internet/MimeMessage could not b
e resolved
synonym : com/sun/mail/handlers/message_rfc822
granting : execute on class com/sun/mail/handlers/multipart_mixed to public
resolving: class com/sun/mail/handlers/multipart_mixed
errors : class com/sun/mail/handlers/multipart_mixed
ORA-29534: referenced object SYS.javax/mail/internet/MimeMultipart could not
be resolved

......

synonym : com/sun/mail/imap/IMAPStore$ConnectionPool
granting : execute on class com/sun/mail/imap/IMAPStore to public
errors : class com/sun/mail/imap/IMAPStore
ORA-29521: referenced name java/lang/AssertionError could not be found

synonym : com/sun/mail/imap/protocol/IMAPSaslAuthenticator$1
granting : execute on class com/sun/mail/imap/protocol/IMAPSaslAuthenticator to
public
errors : class com/sun/mail/imap/protocol/IMAPSaslAuthenticator
ORA-29534: referenced object SYS.com/sun/mail/imap/protocol/IMAPSaslAuthenti
cator$1 could not be resolved
ORA-29521: referenced name javax/security/sasl/SaslException could not be fo
und
ORA-29521: referenced name javax/security/sasl/Sasl could not be found
ORA-29521: referenced name javax/security/sasl/SaslClient could not be found
ORA-29521: referenced name javax/security/auth/callback/CallbackHandler coul
d not be found

email

A reader, April 03, 2008 - 8:41 pm UTC

Tom:

Do you have any hints on the above two oracle errors when we tried to loadjava the mail9i.zip.

Should we email Mark Piermarini? or have we done something wrong? is this the wrong thread for this?

thank you,

email

A reader, April 10, 2008 - 2:30 pm UTC

Tom:

is it true that we cant put a TAR for Oracle 9.2.0.2 anymore on the above issue.

is oracle not supporting this anymore.

thanks

Tom Kyte
April 10, 2008 - 2:54 pm UTC

you can open a tar.

email

A reader, April 10, 2008 - 4:03 pm UTC

Tom:

Thanks.

In the meantime, can you give us a hint.

do we have to compile activation9i.zip before mail9i.zip or you think it is related to the zip file itself, or the iBM aix.
Tom Kyte
April 10, 2008 - 4:06 pm UTC

I don't have access to my 9i system, nor will I, until next week at the earliest. I'm on the road and all I brought with me was 10g and 11g.

If you follow the directions step by step - it should work. If you have a java person around, they can inspect the zips and verify everything that is needed is there.

email

A reader, April 10, 2008 - 4:30 pm UTC

Tom:

OK, thank you for your response. I will look forward for your 9i check next week.

In the meantime, I wil double check the zip files creation and see if i can find a java person to verify it.

email

A reader, April 10, 2008 - 5:00 pm UTC

Tom:

BTW, would 10g or 11g solve the attachement issue. I noticed you mention UTL_MAIL above that seems to send attachements.

just wondering when we upgrade to 10g or 11g, i still need the javamail api or oracle has other apis already installed.
Tom Kyte
April 10, 2008 - 8:34 pm UTC

there are api's to send mail with attachments in subsequent releases - yes, you can read the documentation on otn.oracle.com

mail

A reader, April 17, 2008 - 10:32 pm UTC

Tom:

did you get a chance to run the sun mail api in your 9i database. i want check if you get same compile errors.
Tom Kyte
April 17, 2008 - 10:52 pm UTC

nope, i did not

Monika Bhakuni, April 25, 2008 - 7:40 am UTC

i have tried this code...its working fine and even i have changed the host name according to my system....

but if i need a code for http server so can anybody help me up with that....

as we are using http server
Tom Kyte
April 28, 2008 - 12:39 pm UTC

sorry, but that doesn't make any sense whatsoever.

you are using http server.

so what, you are apparently using a database too.

email attachment

A reader, May 05, 2008 - 10:18 am UTC

Tom:

This what we get on the tar for the java errors. I think this is wrong answer.
Do not your procedures in old book "expert one on one" page 1237 also apply for 9i and 10g. is there new procedures for 9i in the new 9i/10g book.


--------------------------------------------------------
Java mail was supported in 8i, as per Note 120994.1 . Not truly supported for 9i / 10g.
We recommend using UTL_SMTP (9i) and UTL_MAIL (10g), as they are built-in packages to accomdate email functionality from within the database.

Beware: JDK 1.3 is installed in 9i and cannot be upgraded.
Note 131872.1 How To Determine The JDK Version Used by the Oracle JVM in the database

--------------------------------------------------------


Tom Kyte
May 05, 2008 - 2:36 pm UTC

that would not be accurate, anything that is good for java in the jdk loaded in the database should be supported - it is a JVM - a JVM is a JVM. You would have to make sure the java api's you are loading were built for the jdk in the database.

utl_mail doesn't support large attachments, it is not a general purpose replacement.

utl_smtp doesn't do attachments unless you do 100% of the work (ie: encode document, output document bounaries - it - utl_smtp - does NOT DO attachments)

email

A reader, May 05, 2008 - 3:42 pm UTC

TOm:

i am suprised they would have such a false note on metalink.

How can i do this? check the api agaisnt the jdk versions? this could be the issue.

<You would have to make sure the java api's you are loading were built for the jdk in the database. >

Tom Kyte
May 06, 2008 - 12:52 am UTC

you'd want to discuss with a java programmer - they would be able to help you out.

Error loading

Ravi Joshi, May 15, 2008 - 1:54 pm UTC

I am using:
Oracle8i Enterprise Edition Release 8.1.7.0.0
JServer Release 8.1.7.0.0 - Production
Window 2003

While loading the have library I am getting the following errors:

E:\JavaMail>loadjava -u sys/change_on_install@peta -o -r -v -f -noverify -synony
m -g public activation8i.zip

resolving: javax/activation/DataHandler
errors : javax/activation/DataHandler
ORA-29534: referenced object SYS.javax/activation/CommandMap could not be re
solved
skipping : javax/activation/UnsupportedDataTypeException is already resolved
resolving: com/sun/activation/viewers/TextViewer
errors : com/sun/activation/viewers/TextViewer
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
skipping : javax/activation/MimeTypeParseException is already resolved
resolving: com/sun/activation/viewers/ImageViewerCanvas
resolving: com/sun/activation/registries/MimeTypeEntry
resolving: javax/activation/CommandObject
errors : javax/activation/CommandObject
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
resolving: com/sun/activation/viewers/ImageViewer
errors : com/sun/activation/viewers/ImageViewer
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
skipping : javax/activation/DataSource is already resolved
skipping : javax/activation/DataContentHandler is already resolved
skipping : javax/activation/DataSourceDataContentHandler is already resolved
skipping : com/sun/activation/registries/MailcapTokenizer is already resolved
resolving: com/sun/activation/viewers/TextEditor
errors : com/sun/activation/viewers/TextEditor
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
skipping : com/sun/activation/registries/MailcapParseException is already resolv
ed
skipping : javax/activation/ObjectDataContentHandler is already resolved
resolving: com/sun/activation/registries/MailcapFile
errors : com/sun/activation/registries/MailcapFile
ORA-29521: referenced name java/util/LinkedHashMap could not be found
skipping : javax/activation/URLDataSource is already resolved
resolving: com/sun/activation/registries/LineTokenizer
resolving: javax/activation/DataHandlerDataSource
errors : javax/activation/DataHandlerDataSource
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
skipping : javax/activation/DataContentHandlerFactory is already resolved
resolving: javax/activation/FileTypeMap
errors : javax/activation/FileTypeMap
ORA-29534: referenced object SYS.javax/activation/MimetypesFileTypeMap could
not be resolved
resolving: javax/activation/FileDataSource
errors : javax/activation/FileDataSource
ORA-29534: referenced object SYS.javax/activation/FileTypeMap could not be r
esolved
resolving: javax/activation/CommandMap
errors : javax/activation/CommandMap
ORA-29534: referenced object SYS.javax/activation/MailcapCommandMap could no
t be resolved
skipping : javax/activation/MimeTypeParameterList is already resolved
resolving: com/sun/activation/registries/LogSupport
errors : com/sun/activation/registries/LogSupport
ORA-29521: referenced name java/util/logging/Logger could not be found
ORA-29521: referenced name java/util/logging/Level could not be found
skipping : javax/activation/SecuritySupport$5 is already resolved
skipping : javax/activation/SecuritySupport$4 is already resolved
skipping : javax/activation/SecuritySupport$3 is already resolved
skipping : javax/activation/SecuritySupport$1 is already resolved
skipping : javax/activation/SecuritySupport$2 is already resolved
resolving: javax/activation/CommandInfo
errors : javax/activation/CommandInfo
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
resolving: com/sun/activation/registries/MimeTypeFile
errors : com/sun/activation/registries/MimeTypeFile
ORA-29534: referenced object SYS.com/sun/activation/registries/LogSupport co
uld not be resolved
resolving: javax/activation/MailcapCommandMap
errors : javax/activation/MailcapCommandMap
ORA-29534: referenced object SYS.com/sun/activation/registries/MailcapFile c
ould not be resolved
skipping : javax/activation/MimeType is already resolved
skipping : javax/activation/SecuritySupport is already resolved
resolving: javax/activation/DataHandler$1
errors : javax/activation/DataHandler$1
ORA-29534: referenced object SYS.javax/activation/DataHandler could not be r
esolved
resolving: javax/activation/MimetypesFileTypeMap
errors : javax/activation/MimetypesFileTypeMap
ORA-29534: referenced object SYS.com/sun/activation/registries/LogSupport co
uld not be resolved
skipping : javax/activation/ActivationDataFlavor is already resolved

Any help fixing these error would be appreciated.

Thanks,
Ravi



Graham Ball, July 28, 2008 - 9:07 am UTC

Hi Tom,
I've put together a simple procedure based on your example and it sends email fine.
However, in Outlook, I do not see from, to, subject etc. in the header.
In the email body, I get this;
From: Batch_check
Subject: Batch transaction processing failure
To: gball@teachers-group.co.uk

From: Batch_check@teachersassurance.co.uk
Bcc:
Return-Path: Batch_check@teachersassurance.co.uk
Message-ID: <HQTGEXG21PbI7lEOuaw00000b8b@HQTGEXG21P.teachers-group.co.uk>
X-OriginalArrivalTime: 28 Jul 2008 12:28:25.0234 (UTC) FILETIME=[6E676F20:01C8F0AD]


The following batches have not been processed:

516,517

Please investigate immediately

The code is:
connection utl_smtp.connection;
mailhost VARCHAR2(30) := '10.1.50.140';
header VARCHAR2(1000);
sender VARCHAR2(100):='Batch_check';
recipient VARCHAR2(100):= 'gball@teachers-group.co.uk';
ccrecipient VARCHAR2(100):= '';
subject VARCHAR2(100):= 'Batch transaction processing failure';
message VARCHAR2(1000) :='';
err_num NUMBER(10);
err_msg VARCHAR2(100);
begin
message := 'The following batches have not been processed:'||CRLF||CRLF||ls_string||CRLF||CRLF||'Please investigate immediately';
--
-- Start the connection.
--
connection := utl_smtp.open_connection(mailhost,25);
--
-- Handshake with the SMTP server
--
utl_smtp.helo(connection, mailhost);
utl_smtp.mail(connection, sender);
utl_smtp.rcpt(connection, recipient);
utl_smtp.open_data(connection);
--
-- Write the header
--
utl_smtp.write_data(connection, 'Date: '||TO_CHAR(SYSDATE,'dd/mm/yyyy hh24:mi:ss')||crlf );
utl_smtp.write_data(connection, 'From: '||sender||crlf);
utl_smtp.write_data(connection, 'Subject: '||subject||crlf);
utl_smtp.write_data(connection, 'To: '||recipient||crlf);
--
-- The crlf is required to distinguish that what comes next is not simply part of the header..
--
utl_smtp.write_data(connection,''|| crlf );
utl_smtp.write_data(connection, message);
utl_smtp.close_data(connection);
utl_smtp.quit(connection);

I can't see anything wrong with it.
Thanks for your help.
Graham

Tom Kyte
July 29, 2008 - 3:27 pm UTC

nor can I - only that outlook must not be doing something it should be doing. in other email clients, what do you see

Problems with permissions

A. Olsen, July 31, 2008 - 11:34 am UTC

Hi Tom

I am using Oracle 10g Database - OS is AIX5L
I have written the functions mentioned above for sending e-mails with attachments using JavaMail API - thanks for the info - they seem to work just fine.

However, I seem to have a problem granting permanent Java IO permission to files.

Connected as sysdba, I have executed the following regarding a user called s_dba:

SQL> select user from dual;

USER
------------------------------
SYS


SQL> exec dbms_java.grant_permission('S_DBA','java.util.PropertyPermission','*','read,write');

PL/SQL-procedure er udført.

SQL> exec dbms_java.grant_permission('S_DBA','java.net.SocketPermission','*','connect, resolve');

PL/SQL-procedure er udført.

SQL> exec dbms_java.grant_permission('S_DBA','java.io.FilePermission','\tmp\*','read, write');

PL/SQL-procedure er udført.

(Please forgive the Danish output from SQLPLUS :)

I am trying to attach files, that already exist in /tmp and give read/write access to all, f.x.:

-rwxrwxrwx   1 root   system  21704 30 jul 15:07 pic1.jpg
-rw-rw-rw-   1 abc    usr       325 31 jul 08:02 t1.txt

When I send an email, using JavaMail, I receive an error message like the following, every time I try to attach a file:

java.security.AccessControlException: the Permission (java.io.FilePermission /tmp/t1.txt read) has not been granted to S_DBA. The PL/SQL to grant this is dbms_java.grant_permission( 'S_DBA', 'SYS:java.io.FilePermission', '/tmp/t1.txt', 'read' )

To accomplish the task, I execute the command for each file that has to be attached, but how come I cannot grant the permission to "/tmp/*" so it would affect all accessible files?

Thank you

A. Olsen

UPS :-)

A. Olsen, July 31, 2008 - 11:56 am UTC

I seem to have copied a wrong line from SQLPLUS, the one with the obvious error...
But no worries - I have also run the comand with the right slashes:
exec dbms_java.grant_permission('S_DBA','java.io.FilePermission','/tmp/*','read, write');
and:
exec dbms_java.grant_permission('S_DBA','SYS:java.io.FilePermission','/tmp/*','read, write');
- without any effect on the result.

The Oracle documentation states:
To denote all files within a directory, provide the * symbol, as follows:
/private/oracle/*

http://download.oracle.com/docs/cd/B19306_01/java.102/b14187/chnine.htm#BABHDBCJ


Thank you

A. Olsen
Tom Kyte
March 03, 2009 - 9:59 am UTC


Class javax.activation.DataHandler not found in import.

Luciano, September 06, 2008 - 7:44 am UTC

I follow each step from this tutorial, and load JAF before load JavaMail but i has received this error "8:16:01 [0:0] SendJavaMail:5: Class javax.activation.DataHandler not found in import."

Please help.

Oracle version: 9i (9.2.0.1) for windows
OS: Windows XP SP3

Invalid email addresss...Culprit?

Reader, September 25, 2008 - 1:39 pm UTC

Tom,
Can this error "ORA-29278: SMTP transient error: 421 Service not available" occur due to invalid email addresses?
I personally doubt it...Please pour in your ideas?

Tom Kyte
September 25, 2008 - 4:00 pm UTC

if email address validation was on, you would get another error - not a "sorry, smtp just isn't working right now" typically.


like something in the 500 range. 421 means "sorry, not working at all right now"

http://www.greenend.org.uk/rjk/2000/05/21/smtp-replies.html


email

sam, December 12, 2008 - 8:42 am UTC

Tom:

In your example below (for 9i R2 database), is it possible to have "p_subject" data from a CLOB column in a table. Can you show a simple example how you would do it. Would there be a limit if 32000 characters size sent in the subject.


tkyte@TKYTE816> begin
2 mail_pkg.send
3 ( p_sender_email => 'asktom_us@oracle.com',
4 p_from => 'Oracle Database Account <asktom_us@oracle.com>',
5 p_to => mail_pkg.array( 'asktom_us@oracle.com',
'thomas.kyte@oracle.com' ),
6 p_cc => mail_pkg.array( 'tkyte@oracle.com' ),
7 p_bcc => mail_pkg.array( 'utility@aria.us.oracle.com' ),
8 p_subject => 'This is a subject',
9 p_body => 'Hello Tom, this is the mail you need' );
10 end;
11 /

Tom Kyte
December 12, 2008 - 8:52 am UTC

sure, it could be a clob

You would just loop over it using dbms_lob.substr and write bits of it at a time.


line 69:

 68      utl_smtp.write_data( g_mail_conn, '' || g_crlf );
 69      utl_smtp.write_data(g_mail_conn, p_body );
 70      utl_smtp.close_data(g_mail_conn );
 71      utl_smtp.quit(g_mail_conn);



would have to become a loop, something similar to (not debugged or compiled, just consider this psuedo code):
l_len := dbms_lob.getlength(p_body);
l_offset := 1;
while( l_offset <= l_len )
loop
   utl_smtp.write_data( g_mail_conn, dbms_lob.substr(p_body,32000,l_offset) );
   l_offset := l_offset+32000;
end loop;

email

sam, December 12, 2008 - 9:54 am UTC

Tom:

Thank you, i will try that.
another small question

1. Would this pl/sql package work for sending the CLOB as an attachment. It claims it does but i do not see anything in "mail" procedure to select an attachment from a table.

http://searchoracle.techtarget.com/searchOracle/downloads/SendingAttachmentsViaUtl_Smtp.txt

2. My CLOB size is about 6000 - 8000 bytes. The easiest way seems to be UTL_MAIL.SEND_ATTACH_VARCHAR2 even though it has 32K limit.

However, this does not seem available in oracle 9i R2. is this correct?

Tom Kyte
December 12, 2008 - 10:48 am UTC

1) you would have to evaluate it - I didn't write it, you can investigate it.

I wouldn't think it would select from a table, rather I think YOU would select from YOUR table - get a clob and pass it as a parameter.

2) or just put it into the body, it is tiny.

see:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1739411218448
for an approach

email

sam, December 12, 2008 - 11:22 am UTC

tom:

you mean using "html_Email" instead of adding the loop
to "send_mail".

This is a CLOB that has an XML file (might be valid or not). WOuld sending thins in HTML be appropriate more than plain text.

l_len := dbms_lob.getlength(p_body);
l_offset := 1;
while( l_offset <= l_len )
loop
utl_smtp.write_data( g_mail_conn, dbms_lob.substr(p_body,32000,l_offset) );
l_offset := l_offset+32000;
end loop;


Tom Kyte
December 12, 2008 - 12:50 pm UTC

I mean to read the link to see how you can send an attachment.

I don't care if you send it in html, xml, sgml, rtf, whatever - you wanted to send an attachement - that was an example of "how to send an attachment"

email attachment

sam, December 12, 2008 - 6:02 pm UTC

Tom:

This pure PL/SQL procedure works in 9i in sending an attachment. The only thing its send BLOB attachment

1. Do I need to send my CLOB data (xml file) as a CLOB or i can still send it attached as a BLOB using this? would there be any difference.

2. If I have to change it to attach CLOB instead of BLOBs can you assist because I had a bunch of errors.

CREATE OR REPLACE PROCEDURE proc_send_email (
ip_sender VARCHAR2,
ip_receiver VARCHAR2,
ip_subject VARCHAR2,
ip_body VARCHAR2 DEFAULT NULL,
ip_filename VARCHAR2)
IS

conn UTL_SMTP.CONNECTION;

bfile_loc BFILE;
blob_loc BLOB;
bfile_offset NUMBER := 1;
blob_offset NUMBER := 1;
tot_len INTEGER;
raw_chunk RAW(57);
buffer_chunk INTEGER := 57;

invalid_filename EXCEPTION;

cannot_open EXCEPTION;

boundary_tag VARCHAR2(78)
:= '-------411d51fd411d51fd-------';
BEGIN

--Open SMTP connection to outgoing mail server
conn := UTL_SMTP.OPEN_CONNECTION('mail.coinfo.com');

--Register domain of sender
UTL_SMTP.HELO(conn, 'coinfo.com');

--Initialize the mail by specifying a sender
UTL_SMTP.MAIL(conn, ip_sender);

--Register receiver
UTL_SMTP.RCPT(conn, ip_receiver);

--Start the mail header
UTL_SMTP.OPEN_DATA(conn);

-- Specify From:, To:, Subject: and the actual mail body
UTL_SMTP.WRITE_DATA(conn, 'From: ' || ip_sender || utl_tcp.crlf);
UTL_SMTP.WRITE_DATA(conn, 'To: ' || ip_receiver || utl_tcp.crlf);
UTL_SMTP.WRITE_DATA(conn, 'Subject: ' || ip_subject || UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(conn, 'Content-Type: multipart/mixed;
boundary="'||boundary_tag ||'"'|| UTL_TCP.CRLF|| UTL_TCP.CRLF);

-- Register body details
UTL_SMTP.WRITE_DATA(conn, '--'||boundary_tag || UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(conn, 'Content-Type: text/plain' || UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(conn, 'Content-Transfer-Encoding: 7bit' ||
UTL_TCP.CRLF|| UTL_TCP.CRLF );
UTL_SMTP.WRITE_DATA(conn, ip_body|| UTL_TCP.CRLF|| UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(conn, UTL_TCP.CRLF );

-- Register attachment details
UTL_SMTP.WRITE_DATA(conn, '--'||boundary_tag || UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(conn, 'Content-Type: application/pdf;
name="'||ip_filename||'"'|| UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(conn, 'Content-Transfer-Encoding: base64' ||
UTL_TCP.CRLF);
UTL_SMTP.WRITE_DATA(conn, 'Content-Disposition: attachment;
filename="' || ip_filename || '"' || UTL_TCP.CRLF|| UTL_TCP.CRLF);


select clob2blob(file_data) into blob_loc
from files_table
where test_no=150 and ftype='XYZ';

--Comment this since i am selecting file from table
/*
-- Obtain the BFILE locator
bfile_loc := BFILENAME('BFILE_DIR',ip_filename);
IF (DBMS_LOB.FILEEXISTS(bfile_loc)=0) THEN
RAISE invalid_filename;
END IF;
-- Open the input BFILE
DBMS_LOB.FILEOPEN(bfile_loc, DBMS_LOB.FILE_READONLY);
IF (DBMS_LOB.FILEISOPEN(bfile_loc)=0) THEN
RAISE cannot_open;
END IF;

-- Initialize the BLOB locator;
DBMS_LOB.CREATETEMPORARY(blob_loc, TRUE);

-- Open the BLOB
DBMS_LOB.OPEN(blob_loc, DBMS_LOB.LOB_READWRITE);
-- Populate the blob with the whole bfile data

DBMS_LOB.LOADBLOBFROMFILE(blob_loc, bfile_loc, DBMS_LOB.LOBMAXSIZE,
bfile_ offset, blob_offset) ;
*/


-- Obtain length of the populated BLOB
tot_len := DBMS_LOB.GETLENGTH(blob_loc);
-- Display the length of the BLOB
DBMS_OUTPUT.PUT_LINE(
'The length of the BLOB after population is: '||
TO_CHAR(tot_len));

-- Stream the binary data in chunks of 57 to the e-mail server
blob_offset := 1;

WHILE blob_offset < tot_len LOOP
DBMS_LOB.READ(blob_loc, buffer_chunk, blob_offset, raw_chunk);
UTL_SMTP.WRITE_RAW_DATA(conn, UTL_ENCODE.BASE64_ENCODE(raw_chunk));
blob_offset := blob_offset + buffer_chunk;
END LOOP;

UTL_SMTP.WRITE_DATA(conn, UTL_TCP.CRLF||UTL_TCP.CRLF||
'--'||boundary_tag||'--');
UTL_SMTP.CLOSE_DATA(conn);
UTL_SMTP.QUIT(conn);


/*Comment this since seelcting CLOB from table.
-- Release the BLOB
DBMS_LOB.FREETEMPORARY(blob_loc);

-- Close the BFILE
DBMS_LOB.FILECLOSE(bfile_loc);
*/

EXCEPTION
WHEN invalid_filename THEN
UTL_SMTP.QUIT(conn);
RAISE_APPLICATION_ERROR(-20001, 'Invalid filename '||ip_filename);
WHEN cannot_open THEN
UTL_SMTP.QUIT(conn);
RAISE_APPLICATION_ERROR(-20002, 'Error opening filename '||ip_filename);
WHEN UTL_SMTP.TRANSIENT_ERROR OR UTL_SMTP.PERMANENT_ERROR THEN
UTL_SMTP.QUIT(conn);
-- DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
RAISE;
WHEN OTHERS THEN
-- DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
RAISE;
END proc_send_email;
/

-- Here¿s the code to test this process:

BEGIN
proc_send_email('lb@coinfo.com',
'bl@coinfo.com',
'Requested Report details',
'Herewith the details. Pls see attached PDF.',
'Thanks. doc1.pdf');
END;
/

Tom Kyte
December 12, 2008 - 6:15 pm UTC

smk - i already showed you how to send a clob via the Tyler Muth "html email" example.


Please - slow down, understand what you are looking at, don't try to 'hack it together from bits and bytes', design what you need and implement it.



email

sam, December 13, 2008 - 11:57 am UTC

Tom:

I will try that. But as you know this is NOT sending the CLOB as an attachment. I believe it is in the body -- which does not mean it wont work.

In your opinion, when do you decide to send CLOB in an attachment versus body as html or plain text. Which do you think is more practical and useful from a user prespective?

The CLOB is just an xml file that shows product test results. The emails are sent from customer to vendor to show whether the product failed or passed the test. I had to create the column as CLOB because the program that creates this string does not create WELL-FORMED XML.

Internet Explorer seems to open the attachment fine as XML when i set the MIME to xml. However the Firefox generated an parse error and could not open it.


Tom Kyte
December 29, 2008 - 8:01 am UTC

umm, then think about it - it is quite simple.

Just loop over the clob and write 32k of it at a time. done.

why you would mail an XML file in the body however is beyond me. Seems you would want to a) attach it, b) with an appropriate mime type so the person you send it to could actually save it as it was originally intended and do stuff with it.


when you put the xml into the body of the email - you sort of "made it not be xml anymore)

email

A reader, December 15, 2008 - 1:10 pm UTC

Tom:

I tried the html_email procedure for the XML file in CLOB.

It is unreadable. The attachment opened it up nicely in XML format in Internet Explorer.

Is there a way to display it in tree XML hierarchy with HTML email .


Tom Kyte
December 29, 2008 - 10:46 am UTC

you don't say what you did - you did change the mime type and all right.


And no, there is NO WAY using html email to display a XML 'tree', you need software that ingests XML, and prints onto a screen.


And obviously, it is NOT unreadable. "The attachment opened it up nicely in XML format in Internet Explorer.", that sort of proves "mission 100% accomplished".

Look - you need something that ingests XML and displays it the way you want.

That is not SMTP (that is just email)
That is not your email client (they do not typically do that, just like they do not display - say - a word document but rely on word to do that)

You send the XML as an attachment, with the right mime type and assuming the recipient has installed software that can render XML, double clicking on it in their xml client would run the application that can display it.

email

A reader, December 16, 2008 - 6:31 pm UTC

Tom:

Can you resolve this puzzle. I create a clone of your MAIL_PKG and did not change anything and I get this error. The call with original MAIl_PKG runs fine

1  begin
  2  mail_pkg_bk.send(p_sender_email=>'myemail@xyz.com',
  3          p_from=>null,
  4          p_to=>mail_pkg.array('myemail@xyz.com'),
  5          p_cc=>mail_pkg.array(),
  6          p_bcc=>mail_pkg.array(),
  7          p_subject => 'This is email with attachment',
  8          p_body => 'This is the body of the email' );
  9* end;
SQL> /
mail_pkg_bk.send(p_sender_email=>'myemail@xyz.com',
*
ERROR at line 2:
ORA-06550: line 2, column 1:
PLS-00306: wrong number or types of arguments in call to 'SEND'
ORA-06550: line 2, column 1:
PLS-00306: wrong number or types of arguments in call to 'SEND'
ORA-06550: line 2, column 1:
PLS-00306: wrong number or types of arguments in call to 'SEND'
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored

Tom Kyte
December 29, 2008 - 11:33 am UTC

you are sending mail_pkg.array to a package mail_pkg_bk.

The package mail_pkg_bk undoubtedly wants mail_pkg_bk.array's, the type is was defined with

email

A reader, December 18, 2008 - 11:54 am UTC

Tom:

Please disregard the last message. The call was passing paraemters pointing to the old package.

IvyFlora, February 28, 2009 - 2:29 am UTC

Tom,
I am trying to send Email from PL/SQL Procedure
But I am getting this error....

SQL> BEGIN
  2     send_mail ('abc@test.com',
  3                'abc@test.com',
  4                'Hello Abc'
  5               );
  6  END;
  7  / 

BEGIN
*
ERROR at line 1:
ORA-29279: SMTP permanent error: 550 authsmtp08: Host 122.165.23.32: No
unauthenticated relaying permitted
ORA-06512: at "SYS.UTL_SMTP", line 21
ORA-06512: at "SYS.UTL_SMTP", line 99
ORA-06512: at "SYS.UTL_SMTP", line 222
ORA-06512: at "SCOTT.SEND_MAIL", line 12
ORA-06512: at line 2
Tom Kyte
March 03, 2009 - 9:58 am UTC

.... No
unauthenticated relaying permitted ....


that is not ambiguous, your smtp server requires you to log in, I don't have that code in there, you'll need to add it.

Charset Problem in sending emails

vikas, March 18, 2009 - 10:08 am UTC

Hi Tom,

When i send plain text emails using UTL_SMTP. I get special char in the email text. For eg £(GBP) appears like ú, euro appears like Ç but $ appear correctly.

Pl help me with this.

Thanks,

Vikas

Tom Kyte
March 19, 2009 - 9:49 am UTC

email is by default 7 bit ascii. Your gbp and euro are in fact "special characters"

the $ is not, it is in 7 bit ascii.

http://docs.oracle.com/docs/cd/B19306_01/appdev.102/b14258/u_smtp.htm#CHDCFFDI

<quote>
Note that the original SMTP protocol communicates using 7-bit ASCII. Using UTL_SMTP, all text data (in other words, those in VARCHAR2) will be converted to US7ASCII before it is sent over the wire to the server. Some implementations of SMTP servers that support SMTP extension 8BITMIME [RFC1652] support full 8-bit communication between client and server. The body of the DATA command may be transferred in full 8 bits, but the rest of the SMTP command and response should be in 7 bits. When the target SMTP server supports 8BITMIME extension, users of multibyte databases may convert their non-US7ASCII, multibyte VARCHAR2 data to RAW and use the WRITE_RAW_DATA subprogram to send multibyte data using 8-bit MIME encoding.
</quote>

CLOB usage instead of BLOB

Suresh, May 20, 2009 - 3:44 am UTC

Great. This is excellent solution for sending eMails with attachemnt, though using 10g, used this instead of Utl_eMail. This combines with DBMS_XMLQuery,storing xml into CLOB and sending as "xls" attachment. Also placed the "CLOBData Source code" which may replace the class "BLOBDataSouce".

static class CLOBDataSource implements DataSource {
private CLOB data;
private String type;

CLOBDataSource(CLOB data, String type) {
this.type = type;
this.data = data;
}

public InputStream getInputStream() throws IOException {
try {
if (data == null) {
throw new IOException("No data.");
}

return data.getAsciiStream();
} catch (SQLException e) {
throw new IOException(
"Cannot get Ascii data input stream from CLOB.");
}
}

public OutputStream getOutputStream() throws IOException {
throw new IOException("Cannot do this.");
}

public String getContentType() {
return type;
}

public String getName() {
return "CLOBDataSource";
}

email

A reader, June 10, 2009 - 6:21 pm UTC

Tom:

I have an oracle application that sends an email after it saves an order via a job.

The email goes to a main person and CC list of 5 people and one bcc (me).

The main person and I received it. Some CC list people claim they do not get it.

They are all valid emails.

1. Is it possible that this could happen - some not receive it?

2. Does the email log means basically that the job was sheduled to be sent to email server (not actuall sent to email server)?

3. Is thre a way to verify that recepient received it? would the SMTP server log has a record of that.
Tom Kyte
June 11, 2009 - 7:53 am UTC

1) of course, email is not 'reliable', however, could it also be a bug in your application - sure.

2) what email log - you create your OWN email log, if you put in a debug message into the log after successful completion of code (after making all of the email calls and making sure nothing failed) - then you have a record that your end of the SMTP transaction "worked"

3) email doesn't have a 'return receipt for sure' option, it isn't part of the protocol.



suggestion: on the server (database server) use telnet to send email to them, if they do not get it - then it has nothing to do with the database code at all. ctl-f for

remove utl_smtp from the loop, test with telnet


on this page.

email

A reader, June 11, 2009 - 9:26 am UTC

Tom:

There is no bug. Out of every 100 emails they report a few missing - might be related to spam filter or someone deleting it.

The API that saves the order saves an entry into the EMAIL log table and schedules the job that send email.

That record in EMAIL_LOG DOES NOT mean that the oracle server sent the email to the SMTP server. If the job was successful then that is true. If it fails, then oracle could not talk to SMTP server.

After that job schedule ,there is no way Oracle can know whether SMTP server sent it or not,
Tom Kyte
June 11, 2009 - 10:54 am UTC

"there is no bug"

thank you very much for the laugh - sam, aka SMK


"hey, 99 times out of 100 my code works perfectly, the problem therefore cannot be in the code, statistically speaking"


... The API that saves the order saves an entry into the EMAIL log table and
schedules the job that send email.
...

that logic should be:

api saves the order
api schedules job
JOB makes the log entry after successfully sending mail



Alexander, June 11, 2009 - 1:16 pm UTC

Ok, I'll bite. How do you know who that is and why do you always call him "SMK"?

Does this mean if I try and fool you by asking questions with a different name you'll know who it is ;)
Tom Kyte
June 11, 2009 - 3:17 pm UTC

he ("the reader") has those as his initials. I know who it is.

he never identifies himself in the reviewer field that you see (but does in other fields), but he is prolific. He has posted more than any other person on this site ever.

Alexander, June 11, 2009 - 3:57 pm UTC

...but he is prolific. He has posted more than any other person on this site ever.

Laughed my a$$ off. I was afraid I held that title. Since you can identify people you could probably start instituting quotas ;)

email

A reader, June 11, 2009 - 5:38 pm UTC

Tom:

I had to look this one up. That is good.
Prolific = productive, creative, fruitful, fertile

I only post using one email account. Other users could be using MANY email accounts. It is hard to detect unless you analyze how the person writes to know who he is.

You are my oracle hero and best mentor - this is why I ask many questions sometimes.

In many many years of development work I only seen one Tom Kyte with Unusual Brain Power.

You got tell us that Secret Vitamin you use to keep all that information.

Several attach with JavaMail API

Jose Lindo, July 17, 2009 - 2:58 pm UTC

Hello.

I use the JavaMail API, in my database. This is work very well.

Now i need Send several PDF in email. How is possible with this javaMail API
Tom Kyte
July 24, 2009 - 8:50 am UTC

You would read about the java mail API, understand how to use it, then make sure your PLSQL interface to it supports the necessary features

and then you call the plsql routine to invoke the java.

In short, you design and implement it?

UTL_SMTP after delivering mail, how to get acknowledge from each recipient?

YS, July 30, 2009 - 1:36 pm UTC

UTL_SMTP after delivering mail, how to get acknowledge from each recipient?

Thank you so much

Tom Kyte
August 03, 2009 - 5:38 pm UTC

by magic - since no such facility exists in real life.

There is a header you can stick in the email - and the email CLIENT might respect it (I always turn it off - you have no right to know if I read your mail or not).

http://mail.python.org/pipermail/python-list/2001-September/105027.html

UTL_SMTP Mail Delivery status notification

YS, August 03, 2009 - 10:44 am UTC

Hi Tom,

Alert emails are delivering through utl_smtp routine to subscribed customers, regarding their events. Here there is a requirement to store all delivery status notification details of each receipient. how do we get the acknowledgement that the mail has been delivered to perticular subscriber? can you please help me to track mail delivery status.

Thank you
Tom Kyte
August 04, 2009 - 1:55 pm UTC

... how do we get the
acknowledgement that the mail has been delivered to perticular subscriber? ...


you would have to invent a brand new email scheme that doesn't exist and build the infrastructure for it.

There is no way to know that anyone has received your email using SMTP, none. The "read request" header (google around) can be used - but it will not be even a tiny bit usable (because most email clients ignore it and those that do allow the user to say "no, don't tell them i read it")

new line

Helena, August 25, 2009 - 8:03 am UTC

Hi

How do I insert a line break in the e-mail text?
Tom Kyte
August 25, 2009 - 10:02 am UTC

ctl-f for g_crlf on this page

crlf stands for carriage return, line feed

Multi attach with blob method

Jose Lindo, September 07, 2009 - 12:30 pm UTC

I use the blob method to send attach in plsql and java api.
Now i need send multiple attach in same email.
who can change the code in java to accept and process one array of blob, to attach to email.
Tom Kyte
September 07, 2009 - 8:26 pm UTC

you have the above demonstration code that shows the technique

you have access to all of the documentation on the planet regarding the java mail api

you are a developer I would presume

Correctly followed all steps but below is where i am facing problem

Sush..!!, September 10, 2009 - 10:29 am UTC

SQL> desc dummy_blob1 
 Name                            Null?    Type
 ------------------------------- -------- ----
 ID                                       NUMBER
 ATTACHMENT                               LONG RAW


  1  declare
  2        ret_code number;
  3      begin
  4        for i in (select attachment from dummy_blob1 where id=1 )
  5        loop
  6          ret_code := send(
  7                        p_from => 'abc@abc.com',
  8                        p_to => 'xyz@abc.com',
  9                        p_cc => NULL,
 10                      p_bcc => NULL,
 11                       p_subject => 'Use the attached Zip file',
 12                       p_body => 'to send email with attachments....',
 13                       p_smtp_host => '172.16.0.3',
 14                       p_attachment_data => i.attachment,
 15                       p_attachment_type => 'application/octet-stream',
 16                       p_attachment_file_name => 'attachment.doc');
 17         if ret_code = 1 then
 18           dbms_output.put_line ('Successfully sent message...');
 19         else
 20           dbms_output.put_line ('Failed to send message...');
 21         end if;
 22       end loop;
 23*    end;
SQL> /

PL/SQL procedure successfully completed.

I receive email with attachment but the attachment is full of ascii characters and File conversion window opens with message select the encoding that makes your document readable.

I am using 9i Database and outlook express for emails.

i am storing the word document/pdf inside the database.
using forms6i
i have checked data is saved correctly and through forms I am able to invoke the document. 




Tom Kyte
September 14, 2009 - 11:34 am UTC

if it is a pdf, why are you tricking your windows client with a "doc" extension??!?!?!?!?

why not, well, pdf?

Need assistance

Sush..!!, September 17, 2009 - 6:48 am UTC

Tom ,

I am not sure in some cases people may attach PDF and in some cases people may attach Word doc. ( this is OLE Container of 6i forms )

I was testing above with word attachment so i specified file name but still problem is how can it be resolved for encode

I tried both .doc / .pdf but i need something it checks and accordingly encode attachment.

currently only error is opening of attachment which is not correctly read and i know its easy for you to resolve me.

thanks and awaiting your reply.

Tom Kyte
September 17, 2009 - 10:58 am UTC

as I recall, an OLE container wraps the document in OLE "stuff" - the document you retrieve is not a word document anymore.

suggest you head over to otn.oracle.com and participate in the Oracle forms (developer) forums - someone might be able to assist you over there - but basically, you don't really have a word document there, you have an ole container

i tested as u said , I am getting below error

Sush..!!, September 17, 2009 - 8:19 am UTC

SQL> ed
Wrote file afiedt.buf

  1   declare
  2           ret_code number;
  3         begin
  4           for i in (select attachment from dummy_blob1 where id=2 )
  5           loop
  6             ret_code := send(
  7                           p_from => 'abc@abc.com',
  8                           p_to => 'xyz@abc.com',
  9                           p_cc => NULL,
 10                         p_bcc => NULL,
 11                          p_subject => 'Use the attached Zip file',
 12                          p_body => 'to send email with attachments....',
 13                          p_smtp_host => '172.16.0.3',
 14                          p_attachment_data => i.attachment,
 15                          p_attachment_type => 'application/PDF',
 16                          p_attachment_file_name => 'I.ATTACHMENT'||'.'||'PDF');
 17            if ret_code = 1 then
 18              dbms_output.put_line ('Successfully sent message...');
 19            else
 20              dbms_output.put_line ('Failed to send message...');
 21            end if;
 22          end loop;
 23*      end;
SQL> /
 declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: Bulk Bind: Truncated Bind
ORA-06512: at line 4

Now id=2 is PDF file and filename = i dont know the file name as i am not saving anywhere filename in my database.
how can i get correct attachment and encoded one.

email

sam, January 23, 2010 - 12:59 pm UTC

Tom:

I am using MAIL_PKG and UTL_SMTP for sending email order confirmations to customers using oracle 9i.

Some customers noted that the email they receive is stamped 5 hours before actual the time they enter the order.

I found this to be true. If you send an email at 1:51 PM EST I get an email stamped

Saturday, January 23, 2010 8:51 AM

I am using the local host for SMTP server. Is this coming from ORACLE or SMTP server how do you fix that.

I noticed the code has these lines but it does not seem to be showing anywhere in the email.

l_date VARCHAR2(255) default to_Char(sysdate, 'dd Mon yy hh24:mi:ss');

writedata('Date: || l_date);


Tom Kyte
January 25, 2010 - 6:11 am UTC

view the raw message - you might need a timezone added to the date. But look at the RAW message with the header (eg: in thunderbird, I hit ctl-u to see the raw message headers - it'll be there)

....
Received: from localhost (localhost.localdomain [127.0.0.1])
by xxx.us.oracle.com (8.13.1/8.13.1) with SMTP id o0P7xjtG031306;
Mon, 25 Jan 2010 07:59:45 GMT
Date: Mon, 25 Jan 2010 07:59:45 GMT
Message-Id: <201001250759.o0P7xjtG031306@dadbeh07.us.oracle.com>
MIME-Version: 1.0
.........

date

A reader, January 25, 2010 - 6:41 pm UTC

Tom:

Do you mean adding timezone to the oracle database, or
application code or the SMTP server? 

SQL> select dbtimezone from dual;

DBTIME
------
+00:00

1 row selected.

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
25-JAN-10 07.23.29.458814 PM -05:00

1 row selected.

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
-05:00

1 row selected.


The unix server itself does have a timezone and correct date when i do date - u.

Received: from ca9801.na.ems.com (11.38.226.66) by
 glms99901.gonk.rootlnka.net (11.38.195.2) with Microsoft SMTP Server id
 7.0.293.1; Mon, 25 Jan 2010 11:56:58 -0500
X-SENDER-IP: 150.33.201.66
X-SENDER-REPUTATION: 4.5
X-IronPort-AV: E=Sophos;i="4.49,340,1262563200"; 
   d="scan'208";a="865300"
X-SENDER-IP: 141.148.242.22
X-SENDER-REPUTATION: None
X-IronPort-Anti-Spam-Filtered: true
X-IronPort-Anti-Spam-Result: AmUSAGdcXUuMk/EV/2dsb2JhbABAgXaNUwHLA4Q7BA
X-IronPort-AV: E=Sophos;i="4.49,34,12563200"; 
   d="scan'208";a="1050631"
Received: from xx.xyz.org ([150.148.251.33])  by
 dmz.na.ems.com with ESMTP; 25 Jan 2010 16:56:53 +0000
Received: from localhost (localhost [127.0.0.1])      by xxn.xx.org
 (AIX5.3/8.11.6p2/8.11.0) with SMTP id o0PG5878      for
 mike.maloney@ems.com; Mon, 25 Jan 2010 11:56:53 -0500
Message-ID: <201001656.o0PGurq580878@xx.xyz.org>
Date: Mon, 25 Jan 2010 11:56:53 +0000
From: <admin@xxx.orf>
Subject: Order Confiramtion
To: mike.maloney@ems.com
MIME-Version: 1.0
Content-Type: text/plain
Return-Path: admin@xxx.org

Tom Kyte
January 29, 2010 - 8:42 am UTC

I mean adding the timezone to the date you put into the email yourself.

when you print the date in the email, what timezone is the date in, if not in GMT, you'd want to tell it what the timezone is so it knows.

time

A reader, January 28, 2010 - 10:25 am UTC

Tom:

we changed the dbtimezone to "EST" and it did not change anything.

The mail admin said the smtp server is setup right and it is the applicatin. Is this somethign with UTL_SMTP or code i need to use. SYSDATE does nto even use time zones.

Tom Kyte
January 29, 2010 - 3:54 pm UTC

all dates have a timezone - implicitly.

think about this, what piece of software in this mix needs to know the timezone? That would be the email client - when it sees:

5pm, Friday January 29th, 2010

what time is that? It is RELATIVE. You'd need to tell it

5pm - EST, Friday January 29th, 2010


otherwise, if you send email, it'll assume GMT

Mike Kutz, January 29, 2010 - 2:02 pm UTC

Dear A Reader (?sam?)

The e-mail header "Date:" line said the time is "11:27 GMT" (as noted by the "+0:00") while the local host e-mail server said it was "11:27 EST".

Another oddity - the "Date: ..." format does not match the DEFAULT format for the 'l_date' variable. Look for something that is overriding the l_date's default value and not including the timezone correctly.

Also, double check that the following result is accurate:
declare
  l_date varchar2(255);
begin
  -- i don't think the DATE type has timezone information
  -- (compilation fails when using sysdate)
  -- so, you need to use TIMESTAMP
  l_date := to_char(systimestamp, 'Dy, dd Mon yyyy hh24:mi:ss TZR');
  dbms_output.put_line( 'Date:  ' || l_date );
end;
/
SQL>/
Date:  Fri, 29 Jan 2010 14:55:43 -05:00

PL/SQL procedure successfully completed.

SQL> host date -u
Fri Jan 29 19:55:48 UTC 2010

Email

sam, January 30, 2010 - 8:31 am UTC

Tom:

This is really strange!

I am using your MAIL_PKG to send emails.

I tried 3 things:

1) The default setup was using SYSDATE and the timestamp for email recevied was always 5 hours behind.
2) I used SYSTIMESTAMP with timzone as show below. Nothing changed in the email received. Timestamp 5 hours behind.
3) I comented out the variable completely and the timestamp received was correct.

How do you explain that. Is the email client using its own timestamp or the email server or what is going on.

Shall i just keep the date comented out after I open UTL_SMTP connection.

As Mike Kutz said the email message does not even show the format of the l_date variable, so that date in the message must be coming from somewhere else. I wonder if the UTL_SMTP includes sending dates internally.


PROCEDURE send (
p_sender_email IN VARCHAR2,
p_from IN VARCHAR2 DEFAULT NULL,
p_to IN ARRAY DEFAULT ARRAY (),
p_cc IN ARRAY DEFAULT ARRAY (),
p_bcc IN ARRAY DEFAULT ARRAY (),
p_subject IN VARCHAR2 DEFAULT NULL,
p_body IN LONG DEFAULT NULL
)
IS
l_to_list LONG;
l_cc_list LONG;
l_bcc_list LONG;
--1 l_date VARCHAR2 (255) DEFAULT TO_CHAR (SYSDATE, 'dd Mon yy hh24:mi:ss');
--2 l_date VARCHAR2 (255) DEFAULT TO_CHAR (SYSTIMESTAMP, ' dd Mon yyyy hh24:mi:ss TZR');


PROCEDURE writedata (p_text IN VARCHAR2)
AS
BEGIN
IF (p_text IS NOT NULL)
THEN
UTL_SMTP.write_data (g_mail_conn, p_text || g_crlf);
END IF;
END;
BEGIN
g_mail_conn := UTL_SMTP.open_connection (g_mailhost, 25);
UTL_SMTP.helo (g_mail_conn, g_mailhost);
UTL_SMTP.mail (g_mail_conn, p_sender_email);
l_to_list := address_email ('To: ', p_to);
l_cc_list := address_email ('Cc: ', p_cc);
l_bcc_list := address_email ('Bcc: ', p_bcc);
UTL_SMTP.open_data (g_mail_conn);
-- writedata ('Date: ' || l_date);
writedata ('From: ' || NVL (p_from, p_sender_email));
writedata ('Subject: ' || NVL (p_subject, '(no subject)'));
writedata (l_to_list);
writedata (l_cc_list);
UTL_SMTP.write_data (g_mail_conn, '' || g_crlf);
UTL_SMTP.write_data (g_mail_conn, p_body);
UTL_SMTP.close_data (g_mail_conn);
UTL_SMTP.quit (g_mail_conn);
END;




Tom Kyte
February 01, 2010 - 9:51 am UTC

1) hmmm, wonder if the fact you are in EST - which is 5 hours off GMT - might, just might be a clue?

2) hmmm, wonder if you printed out the fact that the timezone was EDT or you left it default AGAIN?

3) the smtp server would have timestamped it itself. Which might be the wrong timestamp depending on when the smtp server recieved the mail and processed it.


How do I explain it? Here, try this sam:

It is 5am. Now Sam, tell me what time is it?

No matter WHAT you respond, you are WRONG. No matter what. Why? Because 5am is ambiguous. The am part might be part of a give away (probably North American - we do the am/pm bit, most of the rest of the planet does 24 hour time). But even then - it would be one of about 8 timezones. It is missing the timezone data.



Sam - seriously - I have to wonder if you read what is typed? Did you really read the comments above from me and others?

email

sam, February 01, 2010 - 10:56 am UTC

Tom:

I did what you said. Does not the SYSTIMESTAMP below tell you correctly what time I am in.


<<I mean adding the timezone to the date you put into the email yourself. 
when you print the date in the email, what timezone is the date in, if not in GMT, you'd want to tell it what the timezone is so it knows>>


I am saying it is 01-FEB-2010 11:11 and 5 hours offset from GMT.

From what i am seeing that L-date variable is not even been looked at.

Can you tell me how to set this correctly and let the email server read this variable correctly.



SQL> select to_char(systimestamp,'dd Mon yyyy hh24:mi:ss TZR') from dual


TO_CHAR(SYSTIMESTAMP,'DDMONYYYYHH24:MI:SSTZR')
-----------------------------------------------------
01 Feb 2010 11:11:50 -05:00

1 row selected.

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
01-FEB-10 11.27.08.054031 AM -05:00

1 row selected.

$ date
Mon Feb  1 11:52:58 EST 2010
$
$ date -u
Mon Feb  1 16:53:15 GMT 2010
$


Tom Kyte
February 01, 2010 - 11:50 am UTC

did you think about looking at what was in the email header sam??????

Did you think to print out what you think you sent.
And then to compare it to what you received?
Debugging 101 sort of stuff?


... Can you tell me how to set this correctly and let the email server read this
variable correctly.
...

research the SMTP standard? That is what I would do. (hint someone gave you the format above... see rfc2822, http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol - anything - research it)

Utl_mail text/html base64

Warren Van Wyck, April 13, 2010 - 8:30 am UTC

With utl_smtp I can send text/html mail with base64 encoding withOUT using an attachment. How does one do this with utl_mail?

Tom Kyte
April 13, 2010 - 9:32 am UTC

you can, but the end user that receives it would probably be annoyed as they receive an email with nothing but gibberish in it that they would have to safe to disk and find a base64 decoder for.

So, the answer is technically "yes", but practically "no"

Message format using UTL_MAIL

Russ, June 03, 2010 - 11:30 am UTC

I need to send a multi-line message body using UTL_MAIL. Inserting CHAR(10) and CHAR(13) at then end of lines does not work.

I can't figure out if DBMS_OUTPUT is available because Send( ) function does not accept arrays in the message field.

Help? Sending one very long line is not readable.
Tom Kyte
June 08, 2010 - 12:01 pm UTC

sorry, but it does "work", it is your email client that is not "working"

ops$tkyte%ORA10GR2> exec utl_mail.send( 'tkyte@localhost', 'tkyte@localhost', subject=>'test', message => 'hello' || chr(10) || 'world' );

PL/SQL procedure successfully completed.

ops$tkyte%ORA10GR2> !mail
Mail version 8.1 6/6/93.  Type ? for help.
"/var/spool/mail/tkyte": 1 message 1 new
>N  1 tkyte@dellpe.localdo  Tue Jun  8 12:56  26/784   "=?ISO-8859-1?Q?test?="
& 1
Message 1:
From tkyte@dellpe.localdomain  Tue Jun  8 12:56:12 2010
Date: Tue, 8 Jun 2010 12:56:12 -0400
From: Thomas Kyte <tkyte@dellpe.localdomain>
To: tkyte@dellpe.localdomain
Subject: =?ISO-8859-1?Q?test?=
X-Priority: 3
Content-Type: multipart/mixed;
 boundary="------------4D8C24=_23F7E4A13B2357B3"

This is a multi-part message in MIME format.
--------------4D8C24=_23F7E4A13B2357B3
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

hello
world



--------------4D8C24=_23F7E4A13B2357B3--

&



It (your client) is doing something, look at the raw email you received (in thunderbird, ctl-u shows it - that'll vary widely be email client) and you'll see.


UTL_MAIL.SEND

Russ, August 10, 2010 - 10:29 am UTC

Tom,

I need to send an email only specifying a comma separated list for BCC. I need the TO and CC to be null. Is this possible?
Tom Kyte
August 18, 2010 - 11:08 pm UTC

I haven't tested this - but try just sending null to recipients.

If that does not work, send it to your account (not your own personal account, some monitoring account - the reply to account you would be using) and then bcc everyone else.


And if you do not like that - use utl_smtp - there you have 100% control over everything.

UTL_MAIL.SEND

A reader, September 01, 2010 - 9:44 am UTC

It's not possible to send a null recipient. Rather not go back to utl_smtp so I'm just using the sender for the recipient. Not ideal but ok.

Follow-up. If I've got a string of hundreds of comma separated addresses and I pass that to Send( ) in the BCC arg, what if one of the address is invalid? And by invalid I don't mean a "real" deliverable address but an address in which the attempt will be made. Will the other valid recipients get an email?

ORA-29279: SMTP permanent error: ORA-29279: SMTP permanent error: 553 5.1.3 <XXXXXXX>... Invalid route address

How to enable TLS in UTL_SMTP package ?

Bhavesh, January 05, 2011 - 7:30 pm UTC

Hi Tom,
I was using the code similar to what you have mentioned in your first reply to send mail from Oracle database using our smtp server. Recently we have migrated to BPOS (Business Productivity online services) from Microsoft for our email.
Microsoft says that they will requires TLS, Transport Layer Security and also port 587 to be configured for SMTP. I can change the port but how can I set TLS layer security in the following code :
create or replace
PROCEDURE send_mail (p_sender IN VARCHAR2,
p_recipient IN VARCHAR2,
p_message IN VARCHAR2)
as
l_mailhost VARCHAR2(255) := 'aria.us.oracle.com';
l_mail_conn utl_smtp.connection;
BEGIN
l_mail_conn := utl_smtp.open_connection(l_mailhost, 25);
utl_smtp.helo(l_mail_conn, l_mailhost);
utl_smtp.mail(l_mail_conn, p_sender);
utl_smtp.rcpt(l_mail_conn, p_recipient);
utl_smtp.open_data(l_mail_conn );
utl_smtp.write_data(l_mail_conn, p_message);
utl_smtp.close_data(l_mail_conn );
utl_smtp.quit(l_mail_conn);
end;

Thanks in advance.
Regards
























<a href= http://www.moviesonline.name/ >watch movies for free</a>























<a href= http://www.moviesonline.name/news/8.html >MovieOnline Pro is available for download.</a>
Tom Kyte
January 06, 2011 - 7:16 am UTC

you would need the new starttls routine

http://docs.oracle.com/docs/cd/E11882_01/appdev.112/e16760/u_smtp.htm#BABJBFGH

available in 11.2

SMTP permanent error: 550 5.1.1 User

parth, March 23, 2011 - 4:02 pm UTC

Hi Tom

I am receiving below error while oracle package try to send and an email. Would you please help me?

ORA-20000: Eror Sending Mail: ORA-29279: SMTP permanent error: 550 5.1.1 User
unknown

Tom Kyte
March 23, 2011 - 4:51 pm UTC

sure, I googled it right up for you - as this is obviously NOT an Oracle error but a SMTP transport error:

http://www.answersthatwork.com/Download_Area/ATW_Library/Networking/Network__3-SMTP_Server_Status_Codes_and_SMTP_Error_Codes.pdf


ctl-f for "test with telnet" on this page and do that with telnet and you'll see it happen without Oracle involved at all.

Issue related to UTL_SMTP

A reader, May 03, 2011 - 5:32 am UTC

Hi Tom

I am sending mail using UTL_SMTP from PL SQL stroed procedure.The mail body is a HTML page having some messages along with a tabular list of user information.It is of datatype CLOB.While sending the mail message,I am reading in chunks of size 1900 bytes.
I have tried to check the 'charset' while sending the mail.I am using the following format:
UTL_SMTP.WRITE_DATA(c,'Content-Type: text/html;charset=UTF-8'|| CHR(13) || CHR(10));

Issue:
When I check the mail sent to my Lotus Notes ID, I could see some unecessary characters e.g. '!' in the body of the mail.There is also some issue with the data in the tabular format .When I check the same mail sent to my GMAIL ID,the mail looks fine without any issues in the mail body.

Your timely help will really be appreciated.

Sned a email attached in PLSQL

Ruben, August 21, 2011 - 8:43 pm UTC

Hello,
i need your help, there's my question:
how i can a send a email attaching the result of a select (select * from dba_users for example) using utl_mail from PLSQL, im working on 11g
Thank you alot.

X-Priority: 1 Content-Type: multipart/mixed; boundary="------------4D8C24=_23F7E4A13B2357B3"

CHETALI, October 05, 2011 - 5:58 am UTC

X-Priority: 1 Content-Type: multipart/mixed; boundary="------------4D8C24=_23F7E4A13B2357B3"

OF no use
Tom Kyte
October 05, 2011 - 10:50 am UTC

I totally agree.

now, if only I knew what the heck you meant...


Others found it of use, perhaps either

a) you are not having the issue they had.
b) you don't understand what you are looking at.

is true? given your input, that is all I can conclude.

EMAIL PACKAGE

A reader, December 06, 2011 - 9:39 pm UTC

Tom:

Just a few simple questions on using your very helpful email package in 9iR2.


tkyte@TKYTE816> begin
2 mail_pkg.send
3 ( p_sender_email => 'asktom_us@oracle.com',
4 p_from => 'Oracle Database Account <asktom_us@oracle.com>',
5 p_to => mail_pkg.array( 'asktom_us@oracle.com',
'thomas.kyte@oracle.com' ),
6 p_cc => mail_pkg.array( 'tkyte@oracle.com' ),
7 p_bcc => mail_pkg.array( 'utility@aria.us.oracle.com' ),
8 p_subject => 'This is a subject',
9 p_body => 'Hello Tom, this is the mail you need' );
10 end;
11 /



1) In the body, how can i make the first line BOLD and LARGER FONT than other text? What codes would you use so the email client can display it like that. I store the message in a table before sending out.


2) I normally use CHR(10) for adding carriage returns. It seems this is a line feed code instead but serves same function.

But on some occasions i notice that an organization mailing address is straight line without returns.

Is this an email client issue? Shall Iuse chr(13) or something else.

This is how my code looks like for the message


l_message := 'Company Mailing Adress'||Chr(10);

if (l_rec.name is not null) then
l_message := l_message||chr(10)||l_rec.name;
end if;

if(l_address1 is not nul null) then
l_message := l_message||chr(10)||l_rec.address1;
end if;

if(l_address2 is not null) then
l_message := l_message||chr(10)||l_rec.address2;
end if;

if (l_city is not null) then
l_message := l_message||chr(10)||l_rec.city;
end if;

...same for city and zip code.




3) How is "p_sender_email" different than "p_from"? IT seems p_sender_email has to be valid email address while the "p_from" is just an email source label that showsthe name of the person or org. etc.


thanks,

ORA-29279: SMTP permanent error: 555 syntax error (#5.5.4)

Hamidur Rahman, December 21, 2012 - 1:14 pm UTC

My Oracle database version is 10g Enterprise Edition Release 10.2.0.1.0 - Production

I'm trying to send mail via UTL_MAIL.SEND. For this what i done..?

1. Connect database as SYS dba
2. successfully run the two things 1.ORACLE_HOME/rdbms/admin/utlmail.sql, 2. ORACLE_HOME/rdbms/admin/prvtmail.plb
3. set smtp_server information by
alter system set smtp_out_server = '172.25.90.165:25' scope=both;

4. SHUTDOWN IMMEDIATE
then
5. startup

all done successfully.

Checked the mail server connectivity by telnet smtp_ip port ...and success.

Run the following code
EXEC UTL_MAIL.SEND(SENDER => 'etl_demo2@mydomain.com',RECIPIENTS => 'etl_demo1@mydomain.com',
SUBJECT => 'Testing UTL_MAIL Option',message => 'blah blah blah');


the out put is
ERROR at line 1:
ORA-29279: SMTP permanent error: 555 syntax error (#5.5.4)
ORA-06512: at "SYS.UTL_SMTP", line 21
ORA-06512: at "SYS.UTL_SMTP", line 99
ORA-06512: at "SYS.UTL_SMTP", line 222
ORA-06512: at "SYS.UTL_MAIL", line 407
ORA-06512: at "SYS.UTL_MAIL", line 594
ORA-06512: at line 2

Looking for your help, please...

send email

A reader, May 23, 2013 - 10:39 pm UTC

Tom:

I was testing sending emails from a new 11g server temporarily using my own exchange server and ran into the following error. 

Does this mean that I need to add my own account user/password to the MAIL_PKG somewhere?
or the exchange system admin need to add the IP address for DB machine to relay server list?
.



SQL> begin
  2  mail_pkg.send
  3  ( p_sender_email => 'Joe.blow@xyz.com',
  4    p_from => 'Oracle Database Account <joe.blow@xyz.com>',
  5    p_to => mail_pkg.array( 'joe.blow@xyz.com' ),
  6    p_cc => mail_pkg.array( 'joe.blow@xyz.com' ),
  7    p_bcc => mail_pkg.array(),
  8    p_subject => 'This is a subject',
  9    p_body => 'Hello Tom, this is the mail you need' );
 10    end;
 11  /
begin
*
ERROR at line 1:
ORA-29279: SMTP permanent error: 530 5.7.1 Client was not authenticated
ORA-06512: at "SYS.UTL_SMTP", line 54
ORA-06512: at "SYS.UTL_SMTP", line 140
ORA-06512: at "SYS.UTL_SMTP", line 469
ORA-06512: at "TIPS.MAIL_PKG", line 60
ORA-06512: at line 2

Tom Kyte
May 29, 2013 - 4:42 pm UTC

this is an SMTP error Sam, you'll have to talk to your email administrator as to what can be done for you here.

SMTP error

A reader, May 30, 2013 - 12:55 pm UTC

Tom:

Yes, I know but I was wondering if there is a way I can add userid/password in your MAIL_PKG for MAIL server authentication or not (similar to when i login to my outlook account).

If that does not work, i think the admin needs to add the DB ip address to the allowed list of relaying messages to Exchange server.
Tom Kyte
May 30, 2013 - 2:58 pm UTC

Sam,

Sam - you have the code, you have the spec. Did I have any place for a username/password to go?


you can write up a routine on your own using UTL_SMTP (which wasn't available way back when I wrote this).

http://docs.oracle.com/cd/E11882_01/appdev.112/e25788/u_smtp.htm


utl_smpt permits you to authenticate to a SMTP server.

Error in sending mail

D, January 20, 2014 - 6:41 am UTC

I am trying to send email to multiple users. But I the error wrong number or types of arguments in call to 'SEND_MULTIPLE_EMAIL'. could you please help

begin
grays_email_handler.send_multiple_email
( p_sender_email => 'd@hotmail.com',
p_from => 'Oracle Database Account <d@hotmail.com>',
p_to => grays_email_handler.array( 'd@hotmail.com', 'd@hotmail.com' ),
p_cc => grays_email_handler.array( 'd@hotmail.com' ),
p_bcc => grays_email_handler.array( 'd@hotmail.com' ),
p_subject => 'This is a subject',
p_body => 'Hello D, this is a test for multiple users' );
end;

how i fill the array dynamic from for loop

alaadin, September 22, 2015 - 8:33 am UTC

how i fill the array dynamic from for loop please help me

send mail error

Elizabeth Ogony, February 01, 2019 - 3:04 pm UTC

Hi Tom, im getting the error below when sending mail to 200 people on Outlook using the procedure shown below. Any ideas on how to fix it will be appreciated...

Unable to send mail to recipients. Error message: ORA-29278: SMTP transient error: 452 4.5.3 Too many recipients
ORA-06512: at "SYS.UTL_SMTP", line 29
ORA-06512: at "SYS.UTL_SMTP", line 108
ORA-06512: at "SYS.UTL_SMTP", line 252
ORA-06512: at "SYS.MAIL_PK

PROCEDURE mail_employee AS
l_to mail_pkg.array := mail_pkg.array();

BEGIN
FOR x IN (SELECT DISTINCT EAEMAL
FROM PRODDTA.F01151
WHERE EAAN8 IN (SELECT LBAN8 FROM PRODDTA.F5608001 WHERE LBLTTP = 'AL' AND (LBLEAVCOM/100) > 15 AND LBAN8 IN (SELECT YAAN8 FROM PRODDTA.F060116 WHERE YAPAST = '0')) AND (EAEMAL is not null and trim(EAEMAL) like '%@%' and EAEMAL like '%xxx%'))

LOOP
l_to.extend;
l_to(l_to.count) := x.EAEMAL;
END LOOP;

mail_pkg.send (p_sender_email => 'JD.email@??.co.ke',
p_from => 'DoNotReply@Jde.??',
p_to => mail_pkg.array(),
p_cc => mail_pkg.array(),
p_bcc => l_to,
p_subject => 'AUTOMATED EMAIL ALERT - LEAVE BALANCE NOTICE',
p_body => 'Dear Colleague,' || chr(10) || 'Please be advised your annual leave balance is above 15 days.' || chr(10) || 'NOTE: Colleagues who do not take their leave days within the stipulated period shall automatically forfeit any days above 15 leave days pending upto that day.');

END mail_employee;
Connor McDonald
February 01, 2019 - 3:16 pm UTC

Error message: ORA-29278: SMTP transient error: 452 4.5.3 Too many recipients

is most likely coming back from your email server. But the solution would be to send emails in batches of (say) 100 at a time.

send mail error

liz, February 04, 2019 - 1:07 pm UTC

Thanks tom for your quick response to my question.

One more thing, could you kindly guide me on how to send the emails in batches of lets say 100. Will i need to call send mail procedure twice?
Chris Saxon
February 04, 2019 - 1:55 pm UTC

You'll need to send ceil ( number recipients / batch size ) emails. Loop this many times, building up the recipient list and sending the email one per iteration.

send mail error

liz, February 04, 2019 - 3:21 pm UTC

Hi tom, I'm still stuck. A sample code snippet would help jog my memory. I have just been coding for a few months now. Thank you.

send mail in batches

liz, February 05, 2019 - 12:40 pm UTC

Hi Tom thank you for your patience. I did get to modify my code as below although i'm not sure if the looping section is correct.I wanna avoid sending unnecessary emails to employees so if you could kindly review it you'll have helped me a lot. thanks.

CREATE OR REPLACE PROCEDURE SYS.mail_employee AS
l_to mail_pkg.array := mail_pkg.array();
TYPE emp_recs_type IS TABLE OF varchar2(200);
emp_recs emp_recs_type;
l_limit number := 40;
Cursor c is
SELECT DISTINCT EAEMAL
FROM PRODDTA.F01151
WHERE EAAN8 IN (SELECT LBAN8 FROM PRODDTA.F5608001 WHERE LBLTTP = 'AL' AND (LBLEAVCOM/100) > 15 AND LBAN8 IN (SELECT YAAN8 FROM PRODDTA.F060116 WHERE YAPAST = '0')) AND (EAEMAL is not null and trim(EAEMAL) like '%@%' and EAEMAL like '%xx%');

BEGIN
Open c;
Loop
Fetch c bulk collect into emp_recs limit l_limit;
exit when emp_recs.count = 0;
for l_index IN emp_recs.FIRST..emp_recs.LAST
Loop
l_to.extend;
l_to(l_to.count) := emp_recs(l_index);
end loop;
mail_pkg.send (p_sender_email => 'JD.email@??.co.ke',
p_from => 'DoNotReply@Jde.??',
p_to => mail_pkg.array(),
p_cc => mail_pkg.array(),
p_bcc => l_to,
p_subject => 'AUTOMATED EMAIL ALERT - LEAVE BALANCE NOTICE',
p_body => 'Dear Colleague,' || chr(10) || 'Please be advised your annual leave balance is above 15 days.' || chr(10) || 'NOTE: Colleagues who do not take their leave days within the stipulated period shall automatically forfeit any days above 15 leave days pending upto that day.');
--End loop;
End Loop;
Close c;
END mail_employee;
/
Chris Saxon
February 05, 2019 - 5:14 pm UTC

    for l_index in emp_recs.first..emp_recs.last loop
      l_to.extend;
      l_to (l_to.count) := emp_recs (l_index);
    end loop;


You're continually adding elements to the end of the l_to array! So each loop will send to all the previous users, plus those added in this batch.

You need to:

l_to.delete

before this loop

PS - please tell me you're NOT creating this in SYS!

send mail in batches

liz, February 05, 2019 - 2:24 pm UTC

Tom, I have run the code as above and the mail got sent to staffs 4 times. I'm guessing its because recipients are 200 and when divided by 40 it gives 4. What corrections will i implement to send only 1 email to employees?. Thank you for your help.

table the discussion

Racer I., February 06, 2019 - 2:16 pm UTC

Hi,

Seems mail_pkg was developed by Tom Kyte. Is this still maintained and all? If so could it (alternatively) take a VARCHAR2-TABLE (like DBMS_SQL.VARCHAR2_TABLE) instead of an ARRRAY?. Then you could pass the bulk collect result directly without having to copy it. Also don't need to delete it as the bulk collect does this for you.
Maybe you can also bulk collect into an ARRAY (haven't tried this).
Also : add code-tags (in curly braces) around code (or use the </> button).

PS : 200 people who didn't (get to) take their vacations. Must be a fascinating job or a hellhole ;)

regards,
Connor McDonald
February 07, 2019 - 2:07 am UTC

Is this still maintained and all?

No. But it's hardly rocket science - it's just wrappers around utl_smtp no?

send mail in batches

liz, March 01, 2019 - 8:39 am UTC

Dear Tom,

Because of you, my send mail program run as desired and I'm most grateful for your help and patience.
Chris Saxon
March 04, 2019 - 10:39 am UTC

Great, glad we could help :)

sending email

spinner, July 08, 2019 - 8:08 am UTC

is this possible to send email from oracle form builder 6.0 ?
if it is possible then how ?

please send me the step by step code or procedure.
Chris Saxon
July 11, 2019 - 3:02 pm UTC

Some other Options, Forms 6i specific

J. Laurindo Chiappa, July 11, 2019 - 4:24 pm UTC

Hi : Chris's answer about sending the email from the database is perfect and works, but IF by any reason you can´t do it (say, the database server don´t have access to the email server), via developer 6i we have some other options :

1. IF your app is running in client/server mode AND exists in the client machine some email client program (Outlook, say) AND OLE is available, THEN you can call the email client via OLE, see https://www.orafaq.com/forum/t/195224/ and http://appldevstuff.blogspot.com/2016/04/oracle-forms-6i-send-mail-alert.html for example

2. IF you have Reports 6i available, you could write a Report and send the report data via email : Oracle reports 6i accepts MAIL as DESTYPE

3. IF you know a little JAVA, you could call from Forms a java program to send the email : I don´t have any specific example for this, but see https://stackoverflow.com/questions/5890868/how-can-i-call-a-java-object-function-from-oracle-forms-6i and http://www.orafaq.com/forum/t/32656 for some java call refs, and https://www.tutorialspoint.com/java/java_sending_email or https://www.javatpoint.com/example-of-sending-email-using-java-mail-api as refs for JAVA MAIL

regards,

Chiappa
Chris Saxon
July 12, 2019 - 8:55 am UTC

Thanks for sharing.

Learn Java

Perry, February 09, 2021 - 12:08 pm UTC

Your information is very beneficial. Thank you for learning a lot of from your website,s information. Wish you great luck !
https://www.javatpoint.com/java-tutorial
Connor McDonald
February 10, 2021 - 4:47 am UTC

Thanks for the feedback.... and the spam :(

Java Tutorial

Vinay Kumar, April 09, 2021 - 8:07 am UTC

Java is a programming lanugage. It is a platform. Java is a high level, robust, object-oriented and secure programming language.
Java was created by Sum Microsystems in the year 1995. James Gosling is known as the father of Java. Before Java, its name was Oak. Since Oak was at that point an enrolled organization, so James Gosling and his group changed the Oak name to Java. When we talk about platform, then it is a hardware or software environment where the program runs. Java has and API; it is called platform.
https://tutorials.ducatindia.com/java/java-tutorial/

java assignment help

java assignment help, June 04, 2021 - 2:54 pm UTC

This company implementing <a href=" https://www.allassignmenthelp.com/java-assignment-help.html" >java assignment help</a> including high-level write my assignment to secure A+ Grade level. Advance fast to our website concerning all assignment help approaching pulling the usual high-grade nature study, there does not do only marketing, we want to generate large connections between our consumer, including nevermore wish to trick you, and inquiring to satisfy our usual honest in respective position and several time, accordingly, please automatically attach with us to imagine more advantageous associations alongside us.
Connor McDonald
June 08, 2021 - 2:36 am UTC

Congratulations. You win the award for most misplaced adjectives in a sentence.

Assignment Help Services

Jessica Jones, June 15, 2021 - 3:09 pm UTC

Get assistance in all kinds of email related queries from the experts of Student Life Saviour at: https://studentlifesaviour.com/sg
Connor McDonald
June 16, 2021 - 6:40 am UTC

wow ... the spam bots are on fire today

Tayl, November 18, 2021 - 6:08 pm UTC

Thank you very much for your thoughtless posts and recommendations!

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library