SlideShare a Scribd company logo
1 of 11
Download to read offline
Introduction

Oracle XML/BI Publisher is a very good reporting tool, which outputs reports into many
formats like Word, Excel, PowerPoint, PDF and even to Adobe Flash. You can deliver
reports generated from XML/BI Publisher to many destinations like email, fax and
printer using delivery manager API’S but it is not directly integrated into the e-business
suite’s concurrent manager so here in this paper I will discuss about how to deliver an
xmlp report to email using PL/SQL.

Using PL/SQL you can write a procedure, which can be submitted as concurrent request
to run any XMLP report. Following steps can be used in the procedure to deliver XMLP
report using PL/SQL:

   1. Submit the XMLP request using FND_REQUEST.SUBMIT_REQUEST
   2. Wait for the request to complete using
      FND_CONCURRENT.WAIT_FOR_REQUEST
   3. Email the output file using UTL_SMTP for file less than 32kb. For files greater
      than 32kb use PKGSENDMAIL given in this paper.



The procedure to submit & email a request is below:

CREATE OR REPLACE PROCEDURE spsendemail(errbuf                   OUT VARCHAR2,
                                        retcode                  OUT VARCHAR2,
                                        papplicationname         IN VARCHAR2,
                                        pprogramshortname        IN VARCHAR2,
                                        planguage                IN VARCHAR2,
                                        pterritory               IN VARCHAR2,
                                        poutputformat            IN VARCHAR2,
                                        precipientemail          IN VARCHAR2) IS
  vdirectory    VARCHAR2(20) := 'OUTFILES';
--set this directory to $APPLCSF/out/<SID>_<hostname>
  vfile         BFILE;
  vfilelen      PLS_INTEGER;
  vmaxlinewidth PLS_INTEGER := 54;
  vbuffer       RAW(2100);
  vamt          BINARY_INTEGER := 672;
  vfilepos      PLS_INTEGER := 1; /* pointer for the file        */
  vconn         UTL_SMTP.connection;
  vdata         RAW(2100);
  vchunks       PLS_INTEGER;
  vmodulo       PLS_INTEGER;
  vpieces       PLS_INTEGER;
  vmimetypebin VARCHAR2(30) := 'application/doc';
  vrequestid    NUMBER(20);
  vflag1        BOOLEAN;
  vflag2        BOOLEAN;
  vreqphase     VARCHAR2(50);
  vreqstatus    VARCHAR2(50);
  vreqdevphase VARCHAR2(50);
  vreqdevstatus VARCHAR2(50);
  vreqmessage   VARCHAR2(50);
BEGIN
--Add layout to the XMLP report
  vflag1 := fnd_request.add_layout(papplicationname,
                                     pprogramshortname,
                                     planguage,
                                     pterritory,
                                     poutputformat);
  --Check if the layout has been submitted
  IF (vflag1) THEN
    fnd_file.put_line(fnd_file.LOG, 'The layout has been submitted');
  ELSE
    fnd_file.put_line(fnd_file.LOG, 'The layout has not been submitted');
  END IF;
  --submit the XMLP report request
  vrequestid := fnd_request.submit_request(application => papplicationname,
                                             program      => pprogramshortname,
                                             description => '',
                                             start_time => '',
                                             sub_request => FALSE);
  COMMIT;
  --Check if the report has been submitted successfully
  IF vrequestid = 0 THEN
    fnd_file.put_line(fnd_file.LOG,
                        'Request Not Submitted due to "' || fnd_message.get ||
'".');
  ELSE
    fnd_file.put_line(fnd_file.LOG,
                        'The Concurrent Request Id is: ' || vrequestid);
  END IF;
  --Wait for the request to complete successfully
  vflag2 := fnd_concurrent.wait_for_request(request_id => vrequestid,
                                              /* interval    => 60,*/
                                              phase       => vreqphase,
                                              status      => vreqstatus,
                                              dev_phase => vreqdevphase,
                                              dev_status => vreqdevstatus,
                                              MESSAGE     => vreqmessage);
  COMMIT;
  --Check for the report completion
  IF (vreqdevphase = 'COMPLETE' AND vreqdevstatus = 'NORMAL') THEN
    BEGIN
       --Begin to email the report
       BEGIN
         vconn := pkgsendmail.fnbeginmail(sender => '<sender@abc.com>',
                                           --enter email of the sender
                                           recipients => precipientemail,
                                           --enter email of the receiver
                                           subject => '<enter subject here>',
                                           --subject of message
                                           mime_type =>
pkgsendmail.vmultipartmimetype);
       END spbeginmail;

      BEGIN
        pkgsendmail.spattachtext(conn      => vconn,
                                 DATA      => '<h3>Please find the following
Attachment</h3><br><br>',
                                 mime_type => 'text/html');
      END spattachtext;

      BEGIN
        pkgsendmail.spbeginattachment(conn           => vconn,
                                      mime_type      => vmimetypebin,
                                      inline         => TRUE,
filename      => pprogramshortname || '_'
||
                                                         vrequestid || '_1.' ||
                                                         poutputformat,
                                         transfer_enc => 'base64');

        BEGIN
          vfile    := BFILENAME(vdirectory,
                                pprogramshortname || '_' || vrequestid ||
                                '_1.' || poutputformat);
          vfilelen := DBMS_LOB.getlength(vfile);
          vmodulo := MOD(vfilelen, vamt);
          vpieces := TRUNC(vfilelen / vamt);

          IF (vmodulo <> 0) THEN
            vpieces := vpieces + 1;
          END IF;

          DBMS_LOB.fileopen(vfile, DBMS_LOB.file_readonly);
          DBMS_LOB.READ(vfile, vamt, vfilepos, vbuffer);
          vdata := NULL;

          FOR i IN 1   ..   vpieces LOOP
            vfilepos   :=   i * vamt + 1;
            vfilelen   :=   vfilelen - vamt;
            vdata      :=   UTL_RAW.CONCAT(vdata, vbuffer);
            vchunks    :=   TRUNC(UTL_RAW.LENGTH(vdata) / vmaxlinewidth);

            IF (i <> vpieces) THEN
              vchunks := vchunks - 1;
            END IF;

            pkgsendmail.spwriteraw(conn    => vconn,
                                   MESSAGE => UTL_ENCODE.base64_encode(vdata));
            vdata := NULL;

            IF (vfilelen < vamt AND vfilelen > 0) THEN
              vamt := vfilelen;
            END IF;

             DBMS_LOB.READ(vfile, vamt, vfilepos, vbuffer);
          END LOOP;
        END;

        DBMS_LOB.fileclose(vfile);
        pkgsendmail.spendattachment(conn => vconn);
      END spbeginattachment;

       pkgsendmail.spendmail(conn => vconn);
    EXCEPTION
       WHEN NO_DATA_FOUND THEN
         pkgsendmail.spendattachment(conn => vconn);
         DBMS_LOB.fileclose(vfile);
       WHEN OTHERS THEN
         pkgsendmail.spendattachment(conn => vconn);
         fnd_file.put_line(fnd_file.LOG, SQLCODE || '-' || SQLERRM);
         DBMS_LOB.fileclose(vfile);
    END;
  ELSE
    fnd_file.put_line(fnd_file.LOG, SQLCODE || '-' || SQLERRM);
  END IF;
END spsendemail;
PL/SQL Code for PKGSENDMAIL package is below:

CREATE OR REPLACE PACKAGE pkgSendMail IS
   vSmtpHost   VARCHAR2(256) := 'localhost.localdomain';
   vSmtpPort   PLS_INTEGER := 25;
   vSmtpDomain VARCHAR2(256) := 'localdomain.com';
   vMailerId           CONSTANT VARCHAR2(256) := 'Mailer by Oracle         UTL_SMTP';
   vBoundary           CONSTANT VARCHAR2(256) := '-----
7D81B75CCC90D2974F7A1CBD';
   vFirstBoundary      CONSTANT VARCHAR2(256) := '--' || vBoundary         ||
                                                 utl_tcp.CRLF;
   vLastBoundary       CONSTANT VARCHAR2(256) := '--' || vBoundary         || '--' ||
                                                 utl_tcp.CRLF;
   vMultipartMimeType CONSTANT VARCHAR2(256) := 'multipart/mixed;          boundary="'
||
                                                 vBoundary || '"';
   vMaxBase64LineWidth CONSTANT PLS_INTEGER := 76 / 4 * 3;

  FUNCTION fnBeginMail(sender        IN    VARCHAR2,
                       recipients    IN    VARCHAR2,
                       subject       IN    VARCHAR2,
                       mime_type     IN    VARCHAR2 DEFAULT 'text/plain',
                       priority      IN    PLS_INTEGER DEFAULT NULL)
    RETURN utl_smtp.connection;

  PROCEDURE spWriteText(conn    IN OUT NOCOPY utl_smtp.connection,
                        message IN VARCHAR2);

  PROCEDURE spWriteRaw(conn    IN OUT NOCOPY utl_smtp.connection,
                       message IN RAW);

  PROCEDURE spAttachText(conn         IN   OUT NOCOPY utl_smtp.connection,
                         data         IN   VARCHAR2,
                         mime_type    IN   VARCHAR2 DEFAULT 'text/plain',
                         inline       IN   BOOLEAN DEFAULT TRUE,
                         filename     IN   VARCHAR2 DEFAULT NULL,
                         last         IN   BOOLEAN DEFAULT FALSE);

  PROCEDURE spBeginAttachment(conn               IN    OUT NOCOPY utl_smtp.connection,
                              mime_type          IN    VARCHAR2 DEFAULT 'text/plain',
                              inline             IN    BOOLEAN DEFAULT TRUE,
                              filename           IN    VARCHAR2 DEFAULT NULL,
                              transfer_enc       IN    VARCHAR2 DEFAULT NULL);

  PROCEDURE spEndAttachment(conn IN OUT NOCOPY utl_smtp.connection,
                            last IN BOOLEAN DEFAULT FALSE);

  PROCEDURE spEndMail(conn IN OUT NOCOPY utl_smtp.connection);

  FUNCTION fnBeginSession RETURN utl_smtp.connection;

  PROCEDURE spBeginMailInSession(conn             IN    OUT NOCOPY utl_smtp.connection,
                                 sender           IN    VARCHAR2,
                                 recipients       IN    VARCHAR2,
                                 subject          IN    VARCHAR2,
                                 mime_type        IN    VARCHAR2 DEFAULT 'text/plain',
                                 priority         IN    PLS_INTEGER DEFAULT NULL);

  PROCEDURE spEndMailInSession(conn IN OUT NOCOPY utl_smtp.connection);

  PROCEDURE spEndSession(conn IN OUT NOCOPY utl_smtp.connection);
END pkgSendMail;
/

CREATE OR REPLACE PACKAGE BODY pkgSendMail IS
  FUNCTION get_address(addr_list IN OUT VARCHAR2) RETURN VARCHAR2 IS
    addr VARCHAR2(256);
    i    pls_integer;

    FUNCTION lookup_unquoted_char(str IN VARCHAR2, chrs IN VARCHAR2)
      RETURN pls_integer AS

      c              VARCHAR2(5);
      i              pls_integer;
      len            pls_integer;
      inside_quote   BOOLEAN;

    BEGIN
      inside_quote := false;
      i             := 1;
      len           := length(str);
      WHILE (i <= len) LOOP
         c := substr(str, i, 1);
         IF (inside_quote) THEN
           IF (c = '"') THEN
             inside_quote := false;
           ELSIF (c = '') THEN
             i := i + 1; -- Skip the quote character
           END IF;
         END IF;
         IF (c = '"') THEN
           inside_quote := true;
         END IF;
         IF (instr(chrs, c) >= 1) THEN
           RETURN i;
         END IF;
         i := i + 1;
      END LOOP;
      RETURN 0;
    END;

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

  PROCEDURE spWriteMimeHeader(conn   IN OUT NOCOPY utl_smtp.connection,
                              name   IN VARCHAR2,
value IN VARCHAR2) IS
BEGIN
  utl_smtp.write_raw_data(conn,
                          utl_raw.cast_to_raw(name || ': ' || value ||
                                              utl_tcp.CRLF));
END;

PROCEDURE spWriteBoundary(conn IN OUT NOCOPY utl_smtp.connection,
                           last IN BOOLEAN DEFAULT FALSE) AS
BEGIN
  IF (last) THEN
     utl_smtp.write_data(conn, vLastBoundary);
  ELSE
     utl_smtp.write_data(conn, vFirstBoundary);
  END IF;
END;

FUNCTION fnBeginMail(sender     IN   VARCHAR2,
                     recipients IN   VARCHAR2,
                     subject    IN   VARCHAR2,
                     mime_type IN    VARCHAR2 DEFAULT 'text/plain',
                     priority   IN   PLS_INTEGER DEFAULT NULL)
  RETURN utl_smtp.connection IS
  conn utl_smtp.connection;
BEGIN
  conn := fnBeginSession;
  spBeginMailInSession(conn,
                       sender,
                       recipients,
                       subject,
                       mime_type,
                       priority);
  RETURN conn;
END;

PROCEDURE spWriteText(conn    IN OUT NOCOPY utl_smtp.connection,
                      message IN VARCHAR2) IS
BEGIN
  utl_smtp.write_data(conn, message);
END;

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

PROCEDURE spAttachText(conn      IN OUT NOCOPY utl_smtp.connection,
                       data      IN VARCHAR2,
                       mime_type IN VARCHAR2 DEFAULT 'text/plain',
                       inline    IN BOOLEAN DEFAULT TRUE,
                       filename IN VARCHAR2 DEFAULT NULL,
                       last      IN BOOLEAN DEFAULT FALSE) IS
BEGIN
  spBeginAttachment(conn, mime_type, inline, filename);
  spWriteText(conn, data);
  spEndAttachment(conn, last);
END;

PROCEDURE spBeginAttachment(conn           IN   OUT NOCOPY utl_smtp.connection,
                            mime_type      IN   VARCHAR2 DEFAULT 'text/plain',
                            inline         IN   BOOLEAN DEFAULT TRUE,
                            filename       IN   VARCHAR2 DEFAULT NULL,
transfer_enc IN VARCHAR2 DEFAULT NULL) IS
BEGIN
  spWriteBoundary(conn);
  spWriteMimeHeader(conn, 'Content-Type', mime_type);
  IF (filename IS NOT NULL) THEN
     IF (inline) THEN
       spWriteMimeHeader(conn,
                         'Content-Disposition',
                         'inline; filename="' || filename || '"');
     ELSE
       spWriteMimeHeader(conn,
                         'Content-Disposition',
                         'attachment; filename="' || filename || '"');
     END IF;
  END IF;
  IF (transfer_enc IS NOT NULL) THEN
     spWriteMimeHeader(conn, 'Content-Transfer-Encoding', transfer_enc);
  END IF;
  utl_smtp.write_data(conn, utl_tcp.CRLF);
END;

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

PROCEDURE spEndMail(conn IN OUT NOCOPY utl_smtp.connection) IS
BEGIN
  spEndMailInSession(conn);
  spEndSession(conn);
END;

FUNCTION fnBeginSession RETURN utl_smtp.connection IS
  conn utl_smtp.connection;
BEGIN
  conn := utl_smtp.open_connection(vSmtpHost, vSmtpPort);
  utl_smtp.helo(conn, vSmtpDomain);
  RETURN conn;
END;

PROCEDURE spBeginMailInSession(conn        IN OUT NOCOPY utl_smtp.connection,
                               sender      IN VARCHAR2,
                               recipients IN VARCHAR2,
                               subject     IN VARCHAR2,
                               mime_type IN VARCHAR2 DEFAULT 'text/plain',
                               priority    IN PLS_INTEGER DEFAULT NULL) IS
  my_recipients VARCHAR2(32767) := recipients;
  my_sender     VARCHAR2(32767) := sender;
BEGIN
  utl_smtp.mail(conn, get_address(my_sender));
  WHILE (my_recipients IS NOT NULL) LOOP
    utl_smtp.rcpt(conn, get_address(my_recipients));
  END LOOP;
  utl_smtp.open_data(conn);
  spWriteMimeHeader(conn, 'From', sender);
  spWriteMimeHeader(conn, 'To', recipients);
  spWriteMimeHeader(conn, 'Subject', subject);
  spWriteMimeHeader(conn, 'Content-Type', mime_type);
  spWriteMimeHeader(conn, 'X-Mailer', vMailerId);
IF (priority IS NOT NULL) THEN
       spWriteMimeHeader(conn, 'X-Priority', priority);
    END IF;
    utl_smtp.write_data(conn, utl_tcp.CRLF);
    IF (mime_type LIKE 'multipart/mixed%') THEN
       spWriteText(conn,
                   'This is a multi-part message in MIME format.' ||
                   utl_tcp.crlf);
    END IF;
  END;

  PROCEDURE spEndMailInSession(conn IN OUT NOCOPY utl_smtp.connection) IS
  BEGIN
    utl_smtp.close_data(conn);
  END;

  PROCEDURE spEndSession(conn IN OUT NOCOPY utl_smtp.connection) IS
  BEGIN
    utl_smtp.quit(conn);
  END;

END;
/



Registering the Concurrent Program:

Create the Executable.
Define the Concurrent Program.




Define all the parameters for the Concurrent Program.
Add the concurrent program to a request group.




Submit the Concurrent request
Submit the Request and supply necessary parameters.
View the status of the request.

More Related Content

What's hot

OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersLin Yo-An
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & ToolsIan Barber
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimizationppd1961
 
Paexec — distributes tasks over network or CPUs
Paexec — distributes tasks over network or CPUsPaexec — distributes tasks over network or CPUs
Paexec — distributes tasks over network or CPUsMinsk Linux User Group
 
11 Things About 11gr2
11 Things About 11gr211 Things About 11gr2
11 Things About 11gr2afa reg
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLsAugusto Pascutti
 
An introduction to PHP 5.4
An introduction to PHP 5.4An introduction to PHP 5.4
An introduction to PHP 5.4Giovanni Derks
 
Programming - Marla Fuentes
Programming - Marla FuentesProgramming - Marla Fuentes
Programming - Marla Fuentesmfuentessss
 
Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Kim Hunmin
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machinejulien pauli
 
Flex lexer.h -c++-- flexlexer.h -- define interfaces f
Flex lexer.h  -c++-- flexlexer.h -- define interfaces fFlex lexer.h  -c++-- flexlexer.h -- define interfaces f
Flex lexer.h -c++-- flexlexer.h -- define interfaces faman39650
 
The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189Mahmoud Samir Fayed
 
Php 5.6 From the Inside Out
Php 5.6 From the Inside OutPhp 5.6 From the Inside Out
Php 5.6 From the Inside OutFerenc Kovács
 
The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180Mahmoud Samir Fayed
 
OpenGurukul : Language : PHP
OpenGurukul : Language : PHPOpenGurukul : Language : PHP
OpenGurukul : Language : PHPOpen Gurukul
 
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅재춘 노
 

What's hot (20)

OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
 
lec4.docx
lec4.docxlec4.docx
lec4.docx
 
Function Call Optimization
Function Call OptimizationFunction Call Optimization
Function Call Optimization
 
Paexec — distributes tasks over network or CPUs
Paexec — distributes tasks over network or CPUsPaexec — distributes tasks over network or CPUs
Paexec — distributes tasks over network or CPUs
 
11 Things About 11gr2
11 Things About 11gr211 Things About 11gr2
11 Things About 11gr2
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
An introduction to PHP 5.4
An introduction to PHP 5.4An introduction to PHP 5.4
An introduction to PHP 5.4
 
Programming - Marla Fuentes
Programming - Marla FuentesProgramming - Marla Fuentes
Programming - Marla Fuentes
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Lexical environment in ecma 262 5
Lexical environment in ecma 262 5Lexical environment in ecma 262 5
Lexical environment in ecma 262 5
 
PHP Internals and Virtual Machine
PHP Internals and Virtual MachinePHP Internals and Virtual Machine
PHP Internals and Virtual Machine
 
Flex lexer.h -c++-- flexlexer.h -- define interfaces f
Flex lexer.h  -c++-- flexlexer.h -- define interfaces fFlex lexer.h  -c++-- flexlexer.h -- define interfaces f
Flex lexer.h -c++-- flexlexer.h -- define interfaces f
 
Control structures
Control structuresControl structures
Control structures
 
The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189The Ring programming language version 1.6 book - Part 81 of 189
The Ring programming language version 1.6 book - Part 81 of 189
 
Php 5.6 From the Inside Out
Php 5.6 From the Inside OutPhp 5.6 From the Inside Out
Php 5.6 From the Inside Out
 
The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180The Ring programming language version 1.5.1 book - Part 74 of 180
The Ring programming language version 1.5.1 book - Part 74 of 180
 
OpenGurukul : Language : PHP
OpenGurukul : Language : PHPOpenGurukul : Language : PHP
OpenGurukul : Language : PHP
 
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
드로이드 나이츠 2018: RxJava 적용 팁 및 트러블 슈팅
 
The new features of PHP 7
The new features of PHP 7The new features of PHP 7
The new features of PHP 7
 

Viewers also liked

Tecnical Apps Interview Questions
Tecnical Apps Interview QuestionsTecnical Apps Interview Questions
Tecnical Apps Interview QuestionsHossam El-Faxe
 
Personalizations Top Ten Rtr
Personalizations Top Ten RtrPersonalizations Top Ten Rtr
Personalizations Top Ten RtrHossam El-Faxe
 
24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...
24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...
24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...Hossam El-Faxe
 
Homeboy Industries "By the Numbers"
Homeboy Industries "By the Numbers"Homeboy Industries "By the Numbers"
Homeboy Industries "By the Numbers"krebsj
 
Homeboys numbers3
Homeboys numbers3Homeboys numbers3
Homeboys numbers3krebsj
 
3970 conferencia homicidios
3970 conferencia homicidios3970 conferencia homicidios
3970 conferencia homicidiosrudyflores
 
3970 luces forenses
3970 luces forenses3970 luces forenses
3970 luces forensesrudyflores
 
Applications Developer 11.5.10
Applications Developer 11.5.10Applications Developer 11.5.10
Applications Developer 11.5.10Hossam El-Faxe
 
Personalizing Oa Framework Pages
Personalizing Oa Framework PagesPersonalizing Oa Framework Pages
Personalizing Oa Framework PagesHossam El-Faxe
 
Oracle Concurrent Program Setup document
Oracle Concurrent Program Setup  documentOracle Concurrent Program Setup  document
Oracle Concurrent Program Setup documentvenkatesh gurusamy
 
Many Faces Of Bi Publisher In Oracle Ebs
Many Faces Of Bi Publisher In Oracle EbsMany Faces Of Bi Publisher In Oracle Ebs
Many Faces Of Bi Publisher In Oracle EbsHossam El-Faxe
 
Apps 11i10 Forms Personalization
Apps 11i10 Forms PersonalizationApps 11i10 Forms Personalization
Apps 11i10 Forms PersonalizationHossam El-Faxe
 
You Oracle Technical Interview
You Oracle Technical InterviewYou Oracle Technical Interview
You Oracle Technical InterviewHossam El-Faxe
 
Order to cash flow cycle in order management
Order to cash flow cycle in order managementOrder to cash flow cycle in order management
Order to cash flow cycle in order managementvenkatesh gurusamy
 

Viewers also liked (20)

Tecnical Apps Interview Questions
Tecnical Apps Interview QuestionsTecnical Apps Interview Questions
Tecnical Apps Interview Questions
 
Personalizations Top Ten Rtr
Personalizations Top Ten RtrPersonalizations Top Ten Rtr
Personalizations Top Ten Rtr
 
24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...
24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...
24221030 Enhance Oracle Sshr With Advanced Personalizations And Oa Fwk Extens...
 
Homeboy Industries "By the Numbers"
Homeboy Industries "By the Numbers"Homeboy Industries "By the Numbers"
Homeboy Industries "By the Numbers"
 
Homeboys numbers3
Homeboys numbers3Homeboys numbers3
Homeboys numbers3
 
PBO01
PBO01PBO01
PBO01
 
3970 conferencia homicidios
3970 conferencia homicidios3970 conferencia homicidios
3970 conferencia homicidios
 
birds
birdsbirds
birds
 
3970 luces forenses
3970 luces forenses3970 luces forenses
3970 luces forenses
 
Applications Developer 11.5.10
Applications Developer 11.5.10Applications Developer 11.5.10
Applications Developer 11.5.10
 
Personalizing Oa Framework Pages
Personalizing Oa Framework PagesPersonalizing Oa Framework Pages
Personalizing Oa Framework Pages
 
Oracle Concurrent Program Setup document
Oracle Concurrent Program Setup  documentOracle Concurrent Program Setup  document
Oracle Concurrent Program Setup document
 
Many Faces Of Bi Publisher In Oracle Ebs
Many Faces Of Bi Publisher In Oracle EbsMany Faces Of Bi Publisher In Oracle Ebs
Many Faces Of Bi Publisher In Oracle Ebs
 
Glinterface
GlinterfaceGlinterface
Glinterface
 
Apps 11i10 Forms Personalization
Apps 11i10 Forms PersonalizationApps 11i10 Forms Personalization
Apps 11i10 Forms Personalization
 
You Oracle Technical Interview
You Oracle Technical InterviewYou Oracle Technical Interview
You Oracle Technical Interview
 
36761374 Oaf
36761374 Oaf36761374 Oaf
36761374 Oaf
 
Order to cash flow cycle in order management
Order to cash flow cycle in order managementOrder to cash flow cycle in order management
Order to cash flow cycle in order management
 
G7 Hackathon 12 2012 Info Sante
G7 Hackathon 12 2012 Info SanteG7 Hackathon 12 2012 Info Sante
G7 Hackathon 12 2012 Info Sante
 
37727897 Oaf Basics
37727897 Oaf Basics37727897 Oaf Basics
37727897 Oaf Basics
 

Similar to Email Using Plsql

Tips
TipsTips
Tipsmclee
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)James Titcumb
 
What RabbitMQ can do for you (phpnw14 Uncon)
What RabbitMQ can do for you (phpnw14 Uncon)What RabbitMQ can do for you (phpnw14 Uncon)
What RabbitMQ can do for you (phpnw14 Uncon)James Titcumb
 
The Story About The Migration
 The Story About The Migration The Story About The Migration
The Story About The MigrationEDB
 
Oracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web ServicesOracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web ServicesKim Berg Hansen
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Aaron Gustafson
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Joseph Scott
 
Why You Should Use TAPIs
Why You Should Use TAPIsWhy You Should Use TAPIs
Why You Should Use TAPIsJeffrey Kemp
 
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019DevClub_lv
 
Cakephp2study tips集
Cakephp2study tips集Cakephp2study tips集
Cakephp2study tips集Kohji Tanaka
 
[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화NAVER D2
 
[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화NAVER D2
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and youmarkstory
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionIan Barber
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021Ayesh Karunaratne
 
PHP, RabbitMQ, and You
PHP, RabbitMQ, and YouPHP, RabbitMQ, and You
PHP, RabbitMQ, and YouJason Lotito
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QAarchwisp
 

Similar to Email Using Plsql (20)

Tips
TipsTips
Tips
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
 
What RabbitMQ can do for you (phpnw14 Uncon)
What RabbitMQ can do for you (phpnw14 Uncon)What RabbitMQ can do for you (phpnw14 Uncon)
What RabbitMQ can do for you (phpnw14 Uncon)
 
The Story About The Migration
 The Story About The Migration The Story About The Migration
The Story About The Migration
 
Oracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web ServicesOracle database - Get external data via HTTP, FTP and Web Services
Oracle database - Get external data via HTTP, FTP and Web Services
 
Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]Fundamental JavaScript [UTC, March 2014]
Fundamental JavaScript [UTC, March 2014]
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )
 
Why You Should Use TAPIs
Why You Should Use TAPIsWhy You Should Use TAPIs
Why You Should Use TAPIs
 
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019Managing State in React Apps with RxJS by James Wright at FrontCon 2019
Managing State in React Apps with RxJS by James Wright at FrontCon 2019
 
Php Enums
Php EnumsPhp Enums
Php Enums
 
Cakephp2study tips集
Cakephp2study tips集Cakephp2study tips集
Cakephp2study tips集
 
Rcpp11
Rcpp11Rcpp11
Rcpp11
 
[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화
 
[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
Test driven infrastructure
Test driven infrastructureTest driven infrastructure
Test driven infrastructure
 
Debugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 VersionDebugging: Rules And Tools - PHPTek 11 Version
Debugging: Rules And Tools - PHPTek 11 Version
 
PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021PHP Enums - PHPCon Japan 2021
PHP Enums - PHPCon Japan 2021
 
PHP, RabbitMQ, and You
PHP, RabbitMQ, and YouPHP, RabbitMQ, and You
PHP, RabbitMQ, and You
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
 

Email Using Plsql

  • 1. Introduction Oracle XML/BI Publisher is a very good reporting tool, which outputs reports into many formats like Word, Excel, PowerPoint, PDF and even to Adobe Flash. You can deliver reports generated from XML/BI Publisher to many destinations like email, fax and printer using delivery manager API’S but it is not directly integrated into the e-business suite’s concurrent manager so here in this paper I will discuss about how to deliver an xmlp report to email using PL/SQL. Using PL/SQL you can write a procedure, which can be submitted as concurrent request to run any XMLP report. Following steps can be used in the procedure to deliver XMLP report using PL/SQL: 1. Submit the XMLP request using FND_REQUEST.SUBMIT_REQUEST 2. Wait for the request to complete using FND_CONCURRENT.WAIT_FOR_REQUEST 3. Email the output file using UTL_SMTP for file less than 32kb. For files greater than 32kb use PKGSENDMAIL given in this paper. The procedure to submit & email a request is below: CREATE OR REPLACE PROCEDURE spsendemail(errbuf OUT VARCHAR2, retcode OUT VARCHAR2, papplicationname IN VARCHAR2, pprogramshortname IN VARCHAR2, planguage IN VARCHAR2, pterritory IN VARCHAR2, poutputformat IN VARCHAR2, precipientemail IN VARCHAR2) IS vdirectory VARCHAR2(20) := 'OUTFILES'; --set this directory to $APPLCSF/out/<SID>_<hostname> vfile BFILE; vfilelen PLS_INTEGER; vmaxlinewidth PLS_INTEGER := 54; vbuffer RAW(2100); vamt BINARY_INTEGER := 672; vfilepos PLS_INTEGER := 1; /* pointer for the file */ vconn UTL_SMTP.connection; vdata RAW(2100); vchunks PLS_INTEGER; vmodulo PLS_INTEGER; vpieces PLS_INTEGER; vmimetypebin VARCHAR2(30) := 'application/doc'; vrequestid NUMBER(20); vflag1 BOOLEAN; vflag2 BOOLEAN; vreqphase VARCHAR2(50); vreqstatus VARCHAR2(50); vreqdevphase VARCHAR2(50); vreqdevstatus VARCHAR2(50); vreqmessage VARCHAR2(50); BEGIN
  • 2. --Add layout to the XMLP report vflag1 := fnd_request.add_layout(papplicationname, pprogramshortname, planguage, pterritory, poutputformat); --Check if the layout has been submitted IF (vflag1) THEN fnd_file.put_line(fnd_file.LOG, 'The layout has been submitted'); ELSE fnd_file.put_line(fnd_file.LOG, 'The layout has not been submitted'); END IF; --submit the XMLP report request vrequestid := fnd_request.submit_request(application => papplicationname, program => pprogramshortname, description => '', start_time => '', sub_request => FALSE); COMMIT; --Check if the report has been submitted successfully IF vrequestid = 0 THEN fnd_file.put_line(fnd_file.LOG, 'Request Not Submitted due to "' || fnd_message.get || '".'); ELSE fnd_file.put_line(fnd_file.LOG, 'The Concurrent Request Id is: ' || vrequestid); END IF; --Wait for the request to complete successfully vflag2 := fnd_concurrent.wait_for_request(request_id => vrequestid, /* interval => 60,*/ phase => vreqphase, status => vreqstatus, dev_phase => vreqdevphase, dev_status => vreqdevstatus, MESSAGE => vreqmessage); COMMIT; --Check for the report completion IF (vreqdevphase = 'COMPLETE' AND vreqdevstatus = 'NORMAL') THEN BEGIN --Begin to email the report BEGIN vconn := pkgsendmail.fnbeginmail(sender => '<sender@abc.com>', --enter email of the sender recipients => precipientemail, --enter email of the receiver subject => '<enter subject here>', --subject of message mime_type => pkgsendmail.vmultipartmimetype); END spbeginmail; BEGIN pkgsendmail.spattachtext(conn => vconn, DATA => '<h3>Please find the following Attachment</h3><br><br>', mime_type => 'text/html'); END spattachtext; BEGIN pkgsendmail.spbeginattachment(conn => vconn, mime_type => vmimetypebin, inline => TRUE,
  • 3. filename => pprogramshortname || '_' || vrequestid || '_1.' || poutputformat, transfer_enc => 'base64'); BEGIN vfile := BFILENAME(vdirectory, pprogramshortname || '_' || vrequestid || '_1.' || poutputformat); vfilelen := DBMS_LOB.getlength(vfile); vmodulo := MOD(vfilelen, vamt); vpieces := TRUNC(vfilelen / vamt); IF (vmodulo <> 0) THEN vpieces := vpieces + 1; END IF; DBMS_LOB.fileopen(vfile, DBMS_LOB.file_readonly); DBMS_LOB.READ(vfile, vamt, vfilepos, vbuffer); vdata := NULL; FOR i IN 1 .. vpieces LOOP vfilepos := i * vamt + 1; vfilelen := vfilelen - vamt; vdata := UTL_RAW.CONCAT(vdata, vbuffer); vchunks := TRUNC(UTL_RAW.LENGTH(vdata) / vmaxlinewidth); IF (i <> vpieces) THEN vchunks := vchunks - 1; END IF; pkgsendmail.spwriteraw(conn => vconn, MESSAGE => UTL_ENCODE.base64_encode(vdata)); vdata := NULL; IF (vfilelen < vamt AND vfilelen > 0) THEN vamt := vfilelen; END IF; DBMS_LOB.READ(vfile, vamt, vfilepos, vbuffer); END LOOP; END; DBMS_LOB.fileclose(vfile); pkgsendmail.spendattachment(conn => vconn); END spbeginattachment; pkgsendmail.spendmail(conn => vconn); EXCEPTION WHEN NO_DATA_FOUND THEN pkgsendmail.spendattachment(conn => vconn); DBMS_LOB.fileclose(vfile); WHEN OTHERS THEN pkgsendmail.spendattachment(conn => vconn); fnd_file.put_line(fnd_file.LOG, SQLCODE || '-' || SQLERRM); DBMS_LOB.fileclose(vfile); END; ELSE fnd_file.put_line(fnd_file.LOG, SQLCODE || '-' || SQLERRM); END IF; END spsendemail;
  • 4. PL/SQL Code for PKGSENDMAIL package is below: CREATE OR REPLACE PACKAGE pkgSendMail IS vSmtpHost VARCHAR2(256) := 'localhost.localdomain'; vSmtpPort PLS_INTEGER := 25; vSmtpDomain VARCHAR2(256) := 'localdomain.com'; vMailerId CONSTANT VARCHAR2(256) := 'Mailer by Oracle UTL_SMTP'; vBoundary CONSTANT VARCHAR2(256) := '----- 7D81B75CCC90D2974F7A1CBD'; vFirstBoundary CONSTANT VARCHAR2(256) := '--' || vBoundary || utl_tcp.CRLF; vLastBoundary CONSTANT VARCHAR2(256) := '--' || vBoundary || '--' || utl_tcp.CRLF; vMultipartMimeType CONSTANT VARCHAR2(256) := 'multipart/mixed; boundary="' || vBoundary || '"'; vMaxBase64LineWidth CONSTANT PLS_INTEGER := 76 / 4 * 3; FUNCTION fnBeginMail(sender IN VARCHAR2, recipients IN VARCHAR2, subject IN VARCHAR2, mime_type IN VARCHAR2 DEFAULT 'text/plain', priority IN PLS_INTEGER DEFAULT NULL) RETURN utl_smtp.connection; PROCEDURE spWriteText(conn IN OUT NOCOPY utl_smtp.connection, message IN VARCHAR2); PROCEDURE spWriteRaw(conn IN OUT NOCOPY utl_smtp.connection, message IN RAW); PROCEDURE spAttachText(conn IN OUT NOCOPY utl_smtp.connection, data IN VARCHAR2, mime_type IN VARCHAR2 DEFAULT 'text/plain', inline IN BOOLEAN DEFAULT TRUE, filename IN VARCHAR2 DEFAULT NULL, last IN BOOLEAN DEFAULT FALSE); PROCEDURE spBeginAttachment(conn IN OUT NOCOPY utl_smtp.connection, mime_type IN VARCHAR2 DEFAULT 'text/plain', inline IN BOOLEAN DEFAULT TRUE, filename IN VARCHAR2 DEFAULT NULL, transfer_enc IN VARCHAR2 DEFAULT NULL); PROCEDURE spEndAttachment(conn IN OUT NOCOPY utl_smtp.connection, last IN BOOLEAN DEFAULT FALSE); PROCEDURE spEndMail(conn IN OUT NOCOPY utl_smtp.connection); FUNCTION fnBeginSession RETURN utl_smtp.connection; PROCEDURE spBeginMailInSession(conn IN OUT NOCOPY utl_smtp.connection, sender IN VARCHAR2, recipients IN VARCHAR2, subject IN VARCHAR2, mime_type IN VARCHAR2 DEFAULT 'text/plain', priority IN PLS_INTEGER DEFAULT NULL); PROCEDURE spEndMailInSession(conn IN OUT NOCOPY utl_smtp.connection); PROCEDURE spEndSession(conn IN OUT NOCOPY utl_smtp.connection);
  • 5. END pkgSendMail; / CREATE OR REPLACE PACKAGE BODY pkgSendMail IS FUNCTION get_address(addr_list IN OUT VARCHAR2) RETURN VARCHAR2 IS addr VARCHAR2(256); i pls_integer; FUNCTION lookup_unquoted_char(str IN VARCHAR2, chrs IN VARCHAR2) RETURN pls_integer AS c VARCHAR2(5); i pls_integer; len pls_integer; inside_quote BOOLEAN; BEGIN inside_quote := false; i := 1; len := length(str); WHILE (i <= len) LOOP c := substr(str, i, 1); IF (inside_quote) THEN IF (c = '"') THEN inside_quote := false; ELSIF (c = '') THEN i := i + 1; -- Skip the quote character END IF; END IF; IF (c = '"') THEN inside_quote := true; END IF; IF (instr(chrs, c) >= 1) THEN RETURN i; END IF; i := i + 1; END LOOP; RETURN 0; END; BEGIN addr_list := ltrim(addr_list); i := lookup_unquoted_char(addr_list, ',;'); IF (i >= 1) THEN addr := substr(addr_list, 1, i - 1); addr_list := substr(addr_list, i + 1); ELSE addr := addr_list; addr_list := ''; END IF; i := lookup_unquoted_char(addr, '<'); IF (i >= 1) THEN addr := substr(addr, i + 1); i := instr(addr, '>'); IF (i >= 1) THEN addr := substr(addr, 1, i - 1); END IF; END IF; RETURN addr; END; PROCEDURE spWriteMimeHeader(conn IN OUT NOCOPY utl_smtp.connection, name IN VARCHAR2,
  • 6. value IN VARCHAR2) IS BEGIN utl_smtp.write_raw_data(conn, utl_raw.cast_to_raw(name || ': ' || value || utl_tcp.CRLF)); END; PROCEDURE spWriteBoundary(conn IN OUT NOCOPY utl_smtp.connection, last IN BOOLEAN DEFAULT FALSE) AS BEGIN IF (last) THEN utl_smtp.write_data(conn, vLastBoundary); ELSE utl_smtp.write_data(conn, vFirstBoundary); END IF; END; FUNCTION fnBeginMail(sender IN VARCHAR2, recipients IN VARCHAR2, subject IN VARCHAR2, mime_type IN VARCHAR2 DEFAULT 'text/plain', priority IN PLS_INTEGER DEFAULT NULL) RETURN utl_smtp.connection IS conn utl_smtp.connection; BEGIN conn := fnBeginSession; spBeginMailInSession(conn, sender, recipients, subject, mime_type, priority); RETURN conn; END; PROCEDURE spWriteText(conn IN OUT NOCOPY utl_smtp.connection, message IN VARCHAR2) IS BEGIN utl_smtp.write_data(conn, message); END; PROCEDURE spWriteRaw(conn IN OUT NOCOPY utl_smtp.connection, message IN RAW) IS BEGIN utl_smtp.write_raw_data(conn, message); END; PROCEDURE spAttachText(conn IN OUT NOCOPY utl_smtp.connection, data IN VARCHAR2, mime_type IN VARCHAR2 DEFAULT 'text/plain', inline IN BOOLEAN DEFAULT TRUE, filename IN VARCHAR2 DEFAULT NULL, last IN BOOLEAN DEFAULT FALSE) IS BEGIN spBeginAttachment(conn, mime_type, inline, filename); spWriteText(conn, data); spEndAttachment(conn, last); END; PROCEDURE spBeginAttachment(conn IN OUT NOCOPY utl_smtp.connection, mime_type IN VARCHAR2 DEFAULT 'text/plain', inline IN BOOLEAN DEFAULT TRUE, filename IN VARCHAR2 DEFAULT NULL,
  • 7. transfer_enc IN VARCHAR2 DEFAULT NULL) IS BEGIN spWriteBoundary(conn); spWriteMimeHeader(conn, 'Content-Type', mime_type); IF (filename IS NOT NULL) THEN IF (inline) THEN spWriteMimeHeader(conn, 'Content-Disposition', 'inline; filename="' || filename || '"'); ELSE spWriteMimeHeader(conn, 'Content-Disposition', 'attachment; filename="' || filename || '"'); END IF; END IF; IF (transfer_enc IS NOT NULL) THEN spWriteMimeHeader(conn, 'Content-Transfer-Encoding', transfer_enc); END IF; utl_smtp.write_data(conn, utl_tcp.CRLF); END; PROCEDURE spEndAttachment(conn IN OUT NOCOPY utl_smtp.connection, last IN BOOLEAN DEFAULT FALSE) IS BEGIN utl_smtp.write_data(conn, utl_tcp.CRLF); IF (last) THEN spWriteBoundary(conn, last); END IF; END; PROCEDURE spEndMail(conn IN OUT NOCOPY utl_smtp.connection) IS BEGIN spEndMailInSession(conn); spEndSession(conn); END; FUNCTION fnBeginSession RETURN utl_smtp.connection IS conn utl_smtp.connection; BEGIN conn := utl_smtp.open_connection(vSmtpHost, vSmtpPort); utl_smtp.helo(conn, vSmtpDomain); RETURN conn; END; PROCEDURE spBeginMailInSession(conn IN OUT NOCOPY utl_smtp.connection, sender IN VARCHAR2, recipients IN VARCHAR2, subject IN VARCHAR2, mime_type IN VARCHAR2 DEFAULT 'text/plain', priority IN PLS_INTEGER DEFAULT NULL) IS my_recipients VARCHAR2(32767) := recipients; my_sender VARCHAR2(32767) := sender; BEGIN utl_smtp.mail(conn, get_address(my_sender)); WHILE (my_recipients IS NOT NULL) LOOP utl_smtp.rcpt(conn, get_address(my_recipients)); END LOOP; utl_smtp.open_data(conn); spWriteMimeHeader(conn, 'From', sender); spWriteMimeHeader(conn, 'To', recipients); spWriteMimeHeader(conn, 'Subject', subject); spWriteMimeHeader(conn, 'Content-Type', mime_type); spWriteMimeHeader(conn, 'X-Mailer', vMailerId);
  • 8. IF (priority IS NOT NULL) THEN spWriteMimeHeader(conn, 'X-Priority', priority); END IF; utl_smtp.write_data(conn, utl_tcp.CRLF); IF (mime_type LIKE 'multipart/mixed%') THEN spWriteText(conn, 'This is a multi-part message in MIME format.' || utl_tcp.crlf); END IF; END; PROCEDURE spEndMailInSession(conn IN OUT NOCOPY utl_smtp.connection) IS BEGIN utl_smtp.close_data(conn); END; PROCEDURE spEndSession(conn IN OUT NOCOPY utl_smtp.connection) IS BEGIN utl_smtp.quit(conn); END; END; / Registering the Concurrent Program: Create the Executable.
  • 9. Define the Concurrent Program. Define all the parameters for the Concurrent Program.
  • 10. Add the concurrent program to a request group. Submit the Concurrent request Submit the Request and supply necessary parameters.
  • 11. View the status of the request.