2. Purpose of this presentation
To show the power of PL/SQL as general programming
system embedded into a database:
● Calling built-in java in Oracle database from PL/SQL
● Performing tasks outside of database with PL/SQL
● Consolidation of different data sources into one single
SQL query
3. The original task
An Oracle-based system receives data from different
external systems. Task: for management and error
tracking purposes present a SQL query that will query
many different systems for a specific item. That query can
be mapped into a web page or used directly from TOAD.
Some other pre-conditions exist:
● Two of the external systems are accessible via web
pages only.
● A few of the external systems can be offline at times.
● The usage of the query should be logged and logging
should be hard to bypass.
4. Limitations and assumptions
● Architectural limitation:
● Do not introduce new inter-database dependencies if no
absolutely necessary
● Accessibility limitation:
● The external systems that expose HTTP interface cannot
be accessed in any other way
● The external systems that expose database access may
be online or offline. (Timeout issues)
● Assumptions:
● All involved systems run some flavour of Unix/Linux
● The delivered amount of data is small enough to reside
in memory
5. Solution outline
● Only well-known technologies used
● “Everything” implemented in PL/SQL
● Database queries
● HTTP queries
● Queries to other databases
● Using embedded java to execute O/S commands
● Running O/S commands to access remote databases
via SQL Plus
● Using pipelined functions to build a dataset for all data
6. Pipelined functions
● Gather data from data sources into an internal dataset
in PL/SQL package
● Table of record
● Traverse table and for every row execute PIPE ROW
● Caller needs to execute statement:
SELECT <…>
from TABLE(<pipelined-function>(<params>))
<where clause, order by clause etc>
7. Pros and cons
● Pros:
● Full control over returned data
● Data acquisition totally obfuscated for caller
● Data can be returned from several disparate sources
with one SQL statement
● Cons:
● Some (small) overhead
● TABLE (…) is not very common construct
8. Example
Code:
Function SelectAll (
itemID IN varchar2
)
return ItemSearchListTab pipelined as
<…some code…>
retidx := returnTab.first;
while retidx is not null loop
pipe row(returnTab(retidx));
retidx := returnTab.next(retidx);
end loop;
SELECT statement:
Select * from table(packageName.SelectAll(’someID’)) order by 1;
9. Using embedded java
● Execute O/S commands:
● Runs as user Oracle in O/S
● Harvest the results into varchar2 variables in code
● Can be used to:
● List contents of directories
● Move and remove files
● Send strings to applications or other systems and
harvest results, in particular:
● Send HTTP queries over network
● Run SQL*Plus and execute SQL scripts on external systems
10. Pros and Cons
● Pros:
● The impossible becomes possible
● Vast opportunities of extending SQL functionality
● Cons:
● Can be misused if left unprotected
12. HTTP Queries
● Use standard Oracle package UTL_HTTP
● Harvest result as string
● Linefeed as line delimiter
● Limitations of result to varchar2 size
● Analyze HTTP output string and fill a PL/SQL table with
results
● Return resulting PL/SQL table as function value
13. Example
HTMLArray := UTL_HTTP.REQUEST_PIECES (searchURL, 20000);
if HTMLArray.count > 0 then
for HTMLLine in HTMLArray.first .. HTMLArray.last loop
tempString := tempString || HTMLArray(HTMLLine);
end loop;
<…some code…>
return returnTab;
14. Queries to other databases
● No inter-database dependencies allowed:
● No database links
● Use external Unix/Linux command to run SQL*Plus with
script
● No changes in local TNSNAMES.ORA
● Use full connection strings
● Harvest output strings into PL/SQL tables
● Unknown connectivity of remote database at given
time:
● Risk for hanging SQL queries
● Use native Unix/Linux function to probe remote node
15. Example – check
connectivity
-- status 0 means port OK, status 1 means port not
available
out_text := os_cmd.run_cmd('nc -w 1
'||connections(cidx).IPAddress||' '||connections(cidx).port||' ;
echo $?');
17. Log queries
● Use Oracle autonomous transactions
● Does not interfere with ”ordinary” operations
18. Wrapping it up
● SQL results, remote dataase queries (not necessarily
Oracle), HTTP calls – all combined into one SQL
statement
● All searches logged
● Not to mention additional functionality:
● Passwords, entered in plain text, stored coded in
dataase
● Passwords retrieved in plain text or verifyed, but only
through code with logging enabled