Professional Documents
Culture Documents
Concurrent Processing
An Oracle White Paper
November 2001
Enhancing Oracle Applications
Concurrent Processing
CONTENTS
1. INTRODUCTION ...........................................................................................................3
2. THE STRUCTURE OF THE PAPER.........................................................................4
2.1 CONCURRENT PROCESSING – A QUICK RECAP ........................................5
3. MANAGING SINGLE CONCURRENT REQUESTS ..........................................6
EXAMPLE 1: REDIRECTING OUTPUT.................................................................7
EXAMPLE 2: RUNNING AN EXTERNAL PROGRAM.....................................8
EXAMPLE 3: INTEGRATING A FAX SERVER.................................................10
4. MANAGING MULTIPLE REQUESTS ...................................................................11
4.1 EXTRACTING VALUES (1): THE BASIC SQL SCRIPT .................................12
4.2 EXTRACTING VALUES (2): THE INTEGRATED APPROACH................13
EXAMPLE 1: WORKING WITH A SINGLE VALUE .......................................13
EXAMPLE 2: WORKING WITH A LIST OF VALUES .....................................14
EXAMPLE 3: WORKING WITH A MULTI-VALUE LIST...............................15
5. LIMITATIONS AND UTILITIES .............................................................................17
5.1 MANIPULATING OUTPUT RECORDS USING PERL..................................17
5.2 PROBLEMS WITH PERL ON WINDOWS NT..................................................18
5.3 SCHEDULING FILE TRANSFERS .......................................................................19
5.4 COMPRESSING & EMAILING DOCUMENTS................................................20
5.5 PDFs AND CONVERSION .....................................................................................21
AUTOMATING PDF PRINTING............................................................................22
AN EXAMPLE CONVERSION ROUTINE ..........................................................22
5.6 SECURITY CONCERNS ...........................................................................................23
6. CONCLUSION ...............................................................................................................23
This paper introduces several techniques that can be used to enhance and automate
the Oracle Applications concurrent processing suite. It starts by presenting some
simple changes that control the concurrent program that they are associated with.
The paper continues by introducing more powerful techniques, which can be
adapted to work on a range of concurrent requests. These examples are more
complex but a lot of effort has gone into ensuring that they are simple enough to
ensure that anybody with a rudimentary knowledge of shell scripting and SQLPlus
should be able to understand them.
In addition to the many benefits of Oracle Alert, the types of automation that you
will be able to achieve by following the examples in this paper include:
As you can see, most of the functions in this list would normally require some form
of manual intervention; however, they can all be automated. In most of cases, the
necessary changes usually only take a few minutes. For example, you can modify the
printer command line to move sensitive files the instant that they complete.
The paper describes conversion routines that you can use to convert a report into a
variety of output formats without having to rerun a concurrent request multiple
times. This type of approach can be easily be extended to automatically zip specific
types of documents or convert them to PDF format, which could then be kept on-
line for differing lengths of time depending on their type. While zipping is simply a
matter of running a utility, conversion to PDF is more involved. There is a
proliferation of document conversion utilities in the public domain; when making
your selection, select those that have a command line interface as these will be easier
to automate.
The final point in the list can give you complete control over archiving and purging.
Although the paper does not propose a full solution, it does provide you will all the
necessary tools to create your own.
This paper is split into three parts. These first two sections describe the techniques
that you can use and include several examples that gradually build in flexibility.
Managing Single Requests: The first part of this paper shows how to control
concurrent output by modifying the printer command. The approach is very easy to
understand and can be implemented very quickly. The examples show a number of
methods that can be used to automatically move the concurrent output to a secure
or alternate directory. This approach is limited in that it only works on the
concurrent program being run whereas the programs in the later half of the paper
are more powerful and will process a range of concurrent requests. The examples
build to show you how you could setup an automatic fax facility.
The final section continues with a discussion of some of the limitations of using
these approaches. For example, dealing with multiple values from each concurrent
request can be problematic and the approach you need to take will differ depending
on whether you are working on UNIX or Windows NT/2000. Should you find that
you have more complex requirements that cannot be handled in a shell script, an
example Perl script provides yet another approach, which also overcomes some of
the system-specific problems.
Finally the paper concludes with a brief discussion of some other utilities such as
Wget and NcFtp that can be useful when transferring programs between machines. It
also describes you how to convert the concurrent output files between different
formats and how you can automatically email them
Please note that although all the examples have been extensively tested (as will
become apparent), you should always perform your own tests.
When designing your own programs, you will be able to intuitively map most of the
columns referred to in this document. However, it may be useful to remember that
the table stores each of the first 25 program arguments separately, and as comma-
separated values in the ARGUMENT_TEXT column.
During normal operation, concurrent managers continuously read requests from this
master queue and run the appropriate operating system jobs, based on the request’s
schedule, priority, and any incompatibility rules. The output files are written to the
$APPLCSF/$APPLOUT directory.
Concurrent programs have a user (visible) name and an internal name. The user
name is stored in the USER_CONCURRENT_PROGRAM_NAME column in
FND_CONCURRENT_PROGRAMS_VL. When developing your scripts, you
could use the CONCURRENT_PROGRAM_NAME, which is not only shorter but
will also make your scripts independent of the NLS_LANG setting. For example,
the internal name of the “Active Users” report is FNDSCURS. One way to find this
is using the Concurrent Programs screen under the Application Developer or System
Administrator responsibilities.
Note: The table and column names may be subject to change between
versions.
This part of the paper shows how to the control concurrent output from the printer
program itself. In this section you will be making changes to a printer driver or
creating a new one, which is described in detail in the Printers chapter of the System
Administration manual. You will need to review that chapter if you do not
understand the association between printer types, print styles, and printer drivers.
Your first design decision is to decide whether you are going to modify an existing
redundant definition or create your own customized combination. The
recommended approach is to create your own with a name that identifies its
purpose.
You can navigate to the Printer Drivers screen as shown in Figure 1 by selecting the
System Administrator responsibility and then Install | Printer | Driver.
• Program: The concurrent manager can call a custom print program and pass
arguments to the program. This provides yet another approach, which
overlaps the examples in this section of the paper. There is no real
difference as far as the examples in this paper are concerned.
This first example shows how a completed report can be immediately moved out of
the $APPLCSF directory. The destination could be a secure location for sensitive
reports or perhaps to directory that is automatically polled by an automatic ftp or fax
program.
Figure 1 shows a standard print (lp) command and its associated arguments as used
on UNIX. On closer inspection, you could run this from the command prompt if
you resolved the variables. This is actually what happens and so to move a file, you
simply need to replace the print (lp) instruction with a move (mv) instruction and
modify the list of the profile options. For example, the move command: mv
$PROFILES$.FILENAME /disk17/secure.is shown in Figure 2. As you can
appreciate, the move command will be run as soon as the job has been completed.
The same principles may be applied to Windows NT/2000 systems.
To ensure that these printer driver examples work, you must have the following
settings:
$PROFILES$.FILENAME includes the operating system path and name for the
output file. If any of the settings above are incorrect then
$PROFILES$.FILENAME will not contain the value that you are expecting.
There are several ways within Applications to run a group of programs together.
Typically you would write your program and then create or add it to a report set. So
as not to confuse the two, this approach differs in that the program, which in this
case is a shell script, is run immediately after the concurrent job completes.
The “redirecting output” example used the operating system command mv to move
the output file. This is simply an executable which can be found in a location
described in the $PATH variable for account that “owns” the Applications
executables. This implies that you can run any program on the Arguments line
provided it exists within the UNIX PATH variable. For example, if you had a shell
script called copyfile.sh, you could run it as shown in Figure 3.
There are two arguments, which are passed to the copyfile.sh shell script. The first is
the output filename including the path and the second is a destination directory.
Specifying the target directory here rather than in the script ensures that the shell
script remains independent and can be used to transfer files to multiple different
directories.
In the following example, although the copyfile.sh script is very simple, it has the
advantage over the first example as it can also keep a log of what has happened. This
shell script simply appends the program parameters to a log file before copying the
file to the “secure” directory.
#!/bin/ksh
FILENAME=`basename $1`
echo "The first parameter was $1" >> /disk17/secure/output.txt
echo "The second parameter was $2" >> /disk17/secure/output.txt
cp $1 $2/$FILENAME
If you wanted to keep individual logs for each concurrent output file, then you
would simply need to change the following two lines :
Note that the first line creates the file, and the second appends information to it.
The example output is as follows:
Although this is a very simple example, it could form the basis for something as
complicated as an output archiving system. You should consider including some
error checking for completeness. Later you will see that the request arguments can
also be extracted and recorded in the log file.
For normal programs, consider If you decide to use this or any other approach in this paper that runs custom
defining a single printer called "printing" steps, an external program, or shell script, then you should realise that the
"Special", with print styles that concurrent request will not be marked as complete until the program completes.
mimic the purpose of the shell You should ensure that the end users understand that they will need to review the
script or program such as "Fax", request log before complaining about performance or calling Oracle Support about a
"Copy", “Move” and so on. hanging concurrent request.
Although there are several fax services available for both UNIX such as Hylafax
(http://www.hylafax.org) and Mgetty+Sendfax (http://alpha.greenie.net/mgetty) they can
be difficult to setup and integrate with Applications. One of the first problems that
you will find is how to extract the fax number from the document. You could pass
the fax number as a program argument, but this can quickly become very tedious.
As most of the Oracle Applications documents have a static layout, you could use a
combination of sed and awk to extract an embedded fax number or destination.
Products such as Mgetty+Sendfax, will resolve the name of the vendor using a
lookup file. However, if you want to add more information such as using a form
overlay, personal signatures or company logos then you probably need to consider a
completely integrated solution such as RightFax (http://www.rightfax.com).
To make this example more interesting, consider a scenario where you have a
Windows PC running as a fax server. This means that in order to fax the file, you
will first need to transfer it to the PC, in which case you will need an ftp server
running on the PC. At this point you will find another problem. You cannot specify
the username, password, or command (i.e. get/put) on the command line for a
normal ftp session and so you need to consider using an alternative such as the
Ncftp client (http://www.ncftp.com). The ncftp program parameters are as follows:
ncftp <options> -u <username> -p <password><host> <path><filename>.
So with a username and password of andy/andy and a the fax server called faxserv
you would use the following command as shown in Figure 4:
The second part of this paper introduces programmatic techniques that can be used
independently of concurrent processing or even Oracle Applications. It starts by
explaining a technique that enables the result of a simple SQL script to be assigned
to a system variable. Later examples deal with reporting the concurrent program
arguments, which are shown in context as a way of cataloguing multiple reports in a
complex archiving system.
In the printer driver examples in the previous section, each of the concurrent
requests must have completed prior to the shell script or program being run. In this
section the scripts can be run manually, as a timed program, or as a separate
concurrent job. This means that you need to understand the phases and status of
each request to avoid system locking issues or working with inappropriate files.
Each concurrent request has a life cycle, proceeding through three or possibly four
phases, which include inactive, pending, running, and completed. Each concurrent
request can have any one a number of possible statuses; the subset that apply to
completed requests are shown in Table 1.
Status Description
Normal Request completes normally.
Error Request failed to complete successfully. Review the log file
for more information.
Warning Request completes with warnings. For example, a report is
generated but fails to print.
Cancelled Pending or Inactive request has been cancelled by a user
setting the status of the request to Cancelled.
Terminated Running request has been terminated by a user setting the
status of the request to Terminated.
Table 1: Completed Request Statuses
Historically, when you have needed to get a value from the database into a system
variable you would need to perform the task manually. For example, you would have
to query the value from the database and then manually assign it to a variable, or
possibly pass it as an argument to a shell script.
This first example shows how to run a SQL script and then automatically assign the
value to a variable. So, lets say that you want to find the most recent concurrent
REQUEST_ID for the ‘Active Users’ report. The SQL script (called getval.sql) that
you would need is as follows:
REM getval.sql
set feedback off
set pagesize 0
SELECT MAX(R.REQUEST_ID)
FROM FND_CONCURRENT_PROGRAMS_VL P,
FND_CONCURRENT_REQUESTS R
WHERE P.CONCURRENT_PROGRAM_ID = R.CONCURRENT_PROGRAM_ID
AND P.USER_CONCURRENT_PROGRAM_NAME = ‘Active Users'
AND R.PHASE_CODE = ‘C’
AND R.STATUS_CODE = ‘C’;
exit
The SQL script switches off all feedback and suppresses the SQL column and row
information (This is important so that only the actual value, the REQUEST_ID is
returned). The SQL query references the user (visible) name. It could have
referenced the internal name – the CONCURRENT_PROGRAM_NAME, as
described in the quick concurrent processing recap section at the start of this
document. This is not only shorter but will also make the script independent of the
NLS_LANG setting.
An example UNIX session to run the script and assign it to a system variable is as
follows. The apps password used throughout this document is “test”.
• SQLPlus is run with the –s option, which suppresses the SQL session login
information.
• The backward quotes are used which tell UNIX to evaluate the expression
before assigning the result to the variable.
• Although the username and password are used in this example, if the script
was going to be run as host concurrent program then you should replace
them with the variable '$FCP_LOGIN'. This avoids the security risk of
having a password hard coded in the script. This is discussed further in the
Security Concerns section of this paper.
This section introduces the concept of integrating a SQL script and assigning the
output to a system variable within a single shell script. There are several examples
that each demonstrate a different feature. The first routine is based on the previous
generic example whereas the subsequent scripts expand on this basic idea to show
you more powerful techniques.
Tip: Although UNIX is used for throughout, if you are using Windows
NT/2000 you can use the shell that comes with the MKS toolkit if you have
Oracle Applications 11i installed. Using this approach for shell scripts should
be considered carefully as the requirement for MKS may not exist in future
Applications releases.
It is perhaps also worth noting at this point that these scripts should work without a
problem in the Bourne (sh) and Korn (ksh) shell, however they will probably not
work without modification in the C shell (csh) or extended C shell (tcsh).
This script produces exactly the same output as the previous example – it returns a
single REQUEST_ID for the most recent “Active Users” report and assigns it to a
UNIX variable. Let’s start by looking at the code and then work out what it is doing.
The easiest way to understand this script is to compare it with the previous basic
example that used a simple SQL script. First, UNIX evaluates the complete
expression between the `` (backward) quotes and then assigns the SQL query result
to the unixvar variable.
Taking a step back, when running a SQL script the @ symbol would normally be
used to denote the name of the file, but in this case it reads the SQL expression until
it encounters the exclamation mark (!). As in the previous example, the SQL script
suppresses the column and row information, runs a single query, and exits back to
UNIX. In order to show the output and demonstrate that the script worked, you
could use the following commands:
$ echo $unixvar
614190
This routine extends the previous approach by retrieving a list of values allowing you
to perform commands on each such as copy, move, zip, or perhaps running a
conversion utility. This approach is more useful when, for example, you want to
archive all the Active Users reports rather than just the latest.
As you can see, the example script below is very similar to the previous example. In
this case the SQL will return all the REQUEST_IDs for all the ‘Active User’ reports.
The UNIX for loop that follows the query simply echoes the request numbers for
each of the reports to demonstrate that each output file can be dealt with in turn.
This is the point where you would place your file commands, include some error
checking and perhaps even record the actions in a log file.
# getreqs
unixvar=`sqlplus -s apps/test @<<!
set termout off
set feedback off
set pagesize 0
select R.REQUEST_ID
from FND_CONCURRENT_PROGRAMS_VL P,
FND_CONCURRENT_REQUESTS R
where P.CONCURRENT_PROGRAM_ID =
R.CONCURRENT_PROGRAM_ID
and P.USER_CONCURRENT_PROGRAM_NAME = 'Active Users'
AND R.PHASE_CODE = ‘C’
AND R.STATUS_CODE = ‘C’;
exit
!`
for unixvar in $unixvar
do
echo "The request number is: $unixvar"
done
$ ./getreqs
The request number is 540185
The request number is 540335
The request number is 540343
The request number is 540345
• All the values are concatenated into a single UNIX variable; the length of
the variables differs depending on the particular platform and so might be a
concern when working with very long lists.
• This example works without a problem as none of the values include
spaces. If there were embedded spaces in any of the fields then you will find
that each value is returned correctly by SQLPlus, but the UNIX for loop
splits each value across multiple lines. In this case, you will need to use a
different approach. The UNIX cut command works well.
The type and range of reports is controlled by the where clause in the SQL query and
instead of listing one particular report, you could simply change it to return say all
the security reports, or perhaps all the FSGs and other financial reports generated
during the month-end processing.
In the preceding examples, each record returned only contains a single value – the
REQUEST_ID. While this may be adequate for very simple situations, in reality you
will normally want to return more information such as the name of the user who ran
the request and perhaps the arguments that were used to run the report. This final
example shows you how to retrieve and manipulate several values for each row
returned. As mentioned in the previous example, this information is essential when
cataloguing reports (such as FSGs) or publishing multiple reports to the web.
Consider a case where you want to move all the Active Users and Signon Audit Users
reports to another location before running the purge concurrent request program.
Let’s say that you also want to record the report parameters.
An example session that runs the program and displays the output is as follows:
$./getsql
The value is : 540550,OPERATIONS,LOGIN_NAME, , OPERATIONS, 01-JAN-99
The value is : 540548,OPERATIONS,
The value is : 540549,OPERATIONS,LOGIN_NAME, , OPERATIONS, 01-JAN-99
The value is : 540185,ASPARSHO,
Note that the SQL script appends a colon(:) to the end of each record. This is used
as a delimiter in the output to identify where each record ends. Also recall that the
UNIX for loop splits values containing spaces across multiple output lines. This
means that the while loop is necessarily more complex to get around this problem.
Without going into too much depth, the script sets the num_of_fields variable to the
You can find out who ran a request number of fields (print NF) in each record using a colon as a field delimiter (-F:).
by linking to the REQUESTED_BY The program could have been shortened by integrating step this into the while loop,
column to FND_USER. but this would have made the program unnecessarily complex. The while loop
contains the sequence of instructions for each record and separates each record
using the UNIX cut function.
Obviously, there are several other ways of delimiting the output and manipulating
each record or field in a record, but this provides some basic ideas and a good
starting point. If you decide to use another approach then you will need to test it
very carefully as several other UNIX commands did not work as well. For example,
as previously mentioned you will find that a very simple array processing for loop will
break the output across another line each time that it encounters a space in the
output stream.
All of the methods up to this point have no problems when dealing with values that
do not include spaces. As all concurrent output filenames are contiguous then this is
not a problem within the context of manipulating concurrent request output files.
This means that you will be able to write very simple shell scripts with a high degree
of confidence.
Example 3 in the last section shows some of the problems when dealing with
embedded spaces. This final section describes an approach using Perl that avoids
some of the limitations of the UNIX examples. If you have a Windows NT/2000
system but do not have MKS installed then this provides another alternative. The
section concludes with a brief discussion of some transfer and conversion utilities
that you will find useful when developing your own programs.
There are several other ways of extracting values from the database and
manipulating the output files. This example uses Perl as it is a common language that
may also be used for Applications maintenance. If you do not have it installed then
you can get a win32 version, which is freely available from
http://aspn.activestate.com/ASPN/Downloads/ActivePerl.
This program functions in much the same way as the previous example.
#!/usr/local/bin/Perl
$statement="
sqlplus -s apps/test @<<!
set termout off
set feedback off
set pagesize 0
select R.REQUEST_ID||','||U.USER_NAME||','||
R.ARGUMENT_TEXT
from FND_CONCURRENT_PROGRAMS_VL P,
FND_CONCURRENT_REQUESTS R,
FND_USER U
where P.CONCURRENT_PROGRAM_ID =
R.CONCURRENT_PROGRAM_ID
and R.REQUESTED_BY = U.USER_ID
and P.USER_CONCURRENT_PROGRAM_NAME IN
('Active Users', 'Signon Audit Users')
AND R.PHASE_CODE = ‘C’
AND R.STATUS_CODE = ‘C’;
exit
! ";
@unixvar=`$statement`;
$length = $#unixvar;
You should easily recognise the SQL component. The @unixvar line runs the SQL
and again, the output is assigned to the unixvar variable. The remainder of the
program is a standard for loop, which will be familiar if you have programmed in
other languages such as C. The only thing that is slightly strange is the chomp
command; this filters the input record separator at the end of each record (simply
cleaning up the end of each record).
Depending on which version you are using and which platform you are on, you may
need to use a separate SQL script. This means that you need to have multiple files,
which although very messy, may mean the difference between being able to achieve
your goal or not. So, the first thing you would need to do is create a file with the
SQL statement, say SQL_AT.SQL and run it using the following command:
The remainder of the program would be exactly the same starting with the @unixvar
line.
There are a number of reasons where scheduling the transfer of large files (including
concurrent reports) after normal working hours or during quiet periods is beneficial.
Not only can this ensure the best network performance for remotely connected
application users in a high latency environment, but it can also even out the network
load, effectively reducing WAN costs.
There are several utilities that can schedule file transfers. For example, the free
versions of Go!Zilla (http://www.gozilla.com) and RealDownload
(http://www.real.com/download) for Windows NT/2000, and GNU Wget
(http://www.gnu.org/software/wget) for UNIX all work well and are relatively easy to
use. The user interfaces for the Windows utilities are self-explanatory. However, in
order to use Wget in a scheduling capacity, you have to use it in conjunction with the
UNIX at command.
A simple example of how you would use at and Wget to download multiple files at a
specific time is as follows:
$ at 18:30
at> wget ftp://apg.uk.oracle.com/pub/A89222-01.zip
at> >Hit CTRL-D at this point<
You should then be returned to your shell prompt, with a job number displayed next
to the timestamp when the job will start, even if you log out of the session. At the
specified time, Wget will wake up and attempt to download the files, in the
background to the directory where the at session was started. This means that
instead of “pushing” files, the control script will need to login to the remote machine
to get the files.
If you want to regularly transfer concurrent output files to a remote site then you
could, for example, use one of the routines in this paper to copy all the files to a
specific local directory. Next you would need to periodically schedule a wget script on
the remote machine to transfer all of the files in the local directory. The wget script
could run once say overnight, or during quite periods if there is no clear batch
processing window.
#!/bin/ksh
wget –P /<target> -o <somepath>/file1.log ftp://oracle.com/pub/A89222-01.zip &
wget –P /<target> -o <somepath>/file2.log ftp://oracle.com/pub/A89223-01.zip &
You would then run this script from the command line. For example:
#at 18:30
at>/<somepath>/myfile.sh
at> >Hit CTRL-D at this point<
When you submit a concurrent request, clicking the Options button in the Submit
Request screen will open the Upon Completion window. An example is shown in
Figure 5. You can use this screen to specify the people or roles to be notified when
the request completes. Setting the Concurrent:Attach URL profile option will
append the output URL to the notification enabling the recipient to view the request
results on-line. This effectively means that you can send the URL to any user or role
defined in Workflow, which is useful when mailing internal users.
There are several situations where you may want to email the output from a
concurrent request. Examples range from simply sending order-related documents
to a supplier to sending financial reports to a company accountant who does not
have direct access to the Applications system. It is clear that emailing documents can
provide a useful alternative to faxing documents (as described in the Integrating A Fax
Server example).
The following program shows you how to uuencode and send a file to a list of
people whose addresses are contained in a file called “mail_list”. The program keeps
a log of the emails sent in a file called “mail_log”.
#!/bin/ksh
# $1 is the filename to send
FILE=$1
subject="$FILE from Oracle Applications"
Note that the recipient will need to understand the uudecode command.
Oracle Applications 11i can automatically produce PDF and HTML output, in
addition to several other standard formats. When you want to create a file in a
variety of output formats, you would normally need to run the concurrent program
several times using different output options each time. Depending on the size of the
report, this may unnecessarily place a considerable load on the server. A better
approach is to run the concurrent program once and then convert the output files
using system utilities. As you have seen, running conversions programs automatically
can be very achieved using any of the techniques presented in this paper.
However, before considering file conversion, it is worth reviewing the PDF format,
which is one of the de facto standards for electronic distribution of documents.
They are created from postscript files (postscript is a programming language that
describes how the printed page should look) and can contain text, images, forms or
even movies. In Applications terms, this means that they can eliminate the need for
costly pre-printed forms. A PDF is considerably smaller than its corresponding
postscript file and can be viewed by anyone with a free Acrobat Reader or directly
from within Oracle Applications.
It is also worth mentioning that you cannot send a PDF direct to a printer; instead
you need to convert it back to postscript format first. This happens automatically in
Applications when a user reviews the file using Acrobat Reader and prints it locally.
If you want to print the file on UNIX you will need to install the Acrobat Reader.
To convert and print the PDF, you would use the command:
Note that if acrobat is not in the path, you will need to specify the complete path.
While you could use this command in a shell script, you can also print PDFs
automatically from the concurrent manager by changing the print command (as
shown in the Printer Drivers Screen in Figure 1) to the following:
Converting files is generally a very simple process. Consider the case where you want
to convert a postscript file into a PDF, but do not have Adobe Acrobat installed.
You could for example use a utility called Ghostscript which it available from
http://www.ghostscript.com. Not only does it have a command line interface that is well
documented and very easy to use, but it also runs on most platforms. In order to
convert a postscript file called infile.ps to mypdf.pdf on Windows you could use the
following command line:
Most of these programs in this paper require usernames and passwords when used
outside of the context of the concurrent manager. A number of techniques exist for
passing usernames and passwords to scripts. Although a detailed discussion of
password security is outside the scope of this paper, one technique is to store
usernames and passwords in a text file which is protected using the operating system
security. A simple shell scripts could access this file to obtain the passwords as
required; effectively eliminating the need to hardcode passwords in scripts.
#ora_passwd
#This is a protected password file
apps/test
system/mypassword
The following simple shell script will return the username and password in the
correct format (i.e. username/password):
An alternative is to run the shell script as a host concurrent program. This approach
is described in the “Host Language Concurrent Programs” section of the System
Administration manual. To have the username/password passed as an environment
variable, you need to enter the term ’ENCRYPT’ in the Execution Options field of
the Register Concurrent Programs window when defining a concurrent program.
This signals the concurrent manager to pass the username/password in the
environment variable $FCP_LOGIN.
6. CONCLUSION
This paper has introduced you to several techniques that can be used to enhance and
automate the Oracle Applications concurrent processing suite. They have ranged
from simple changes to the printer driver through shell scripts to Perl programs and
as you can see, most of the examples are very quick and easy to implement.
As you have seen, you can retrieve any information from the database using the
embedded SQL approach described in this paper. You may have also realised that
you can just as easily insert, update, or delete records using the same type of shell
script. However, it is STRONGLY RECOMMENDED that you do not do this as
you risk corrupting your database and irreparably damaging all of your applications.
Apart from the simple benefits of being able to move sensitive reports or
automatically zipping and distributing documents across WANs during quiet
periods, you have the opportunity to build a very compressive archive routine that
can be used for example to catalogue, separate and organize month end reports.
Oracle Corporation
World Headquarters
500 Oracle Parkway
Redwood Shores, CA 94065
U.S.A.
Worldwide Inquiries:
Phone: +1.650.506.7000
Fax: +1.650.506.7200
www.oracle.com