Just as stored procedures may be written in PL/SQL (Oracle's native language) and then called from PL/SQL, directly, or from Java using JDBC, so too stored procedures may be written in Java and called from PL/SQL or Java.
Before Oracle 10g, calling stored procedures from Java was
Code Block |
---|
package org.glast.pipeline.server.sql.sp; public class SPStream { // Package-specific Exception types: public static final int invalid_stream_ex PROCEDURE SetProcessInstanceStatus(ProcessInstance_in IN int, ProcessingStatus_in IN VARCHAR2, transitionTime_in IN TimeStamp) IS ProcessInstanceRow_out ProcessInstance%ROWTYPE; ProcessType_out ProcessType.ProcessType%TYPE; = -20026StreamStatus_out StreamStatus.StreamStatus%TYPE; // ProcessingStatus Enumeration Constants: BEGIN public static final String select * ps_waiting = "WAITING"; public static final Stringinto ProcessInstanceRow_out ps_ready = from "READY";ProcessInstance public static final String ps_queued where ProcessInstance = ProcessInstance_in; "QUEUED"; public staticselect finalProcessType String ps_submitted = "SUBMITTED";into ProcessType_out public static final String ps_running from Process = "RUNNING"; public static final String where Process = ps_successProcessInstanceRow_out.Process; = "SUCCESS"; IF 0 public static final String= GetStateTransitionValid(ProcessInstanceRow_out.ProcessingStatus, ProcessingStatus_in, ProcessType_out) THEN ps_failed = "FAILED";RAISE_APPLICATION_ERROR(invalid_status_transition_ex, public static final String ps_terminated = 'Not a "TERMINATED"; valid state transition publicfrom static' final|| String ps_canceled = "CANCELED"; public static final StringProcessInstanceRow_out.ProcessingStatus || ps_skipped = "SKIPPED"; ' //to StreamStatus Enumeration Constants: ' || public static final String ss_waiting = "WAITING";ProcessingStatus_in || public static final String ss_queued = ' for "QUEUED"; a process of publictype static' final|| String ss_running = "RUNNING"; public static final StringProcessType_out || ss_success = "SUCCESS";'.'); public static final String ss_failed = "FAILED"RETURN; public static final String END ss_terminatedIF; = update "TERMINATED";ProcessInstance public static final String ss_canceled set ProcessingStatus = "CANCELED";ProcessingStatus_in public static final String ss_terminating where ProcessInstance = ProcessInstance_in; "TERMINATING"; public static final String IF ps_submitted = ProcessingStatus_in THEN ss_canceling = update "CANCELING";ProcessInstance private static HashSet processingStates = new HashSet(); static { set SubmitDate = processingStates.add(ps_waiting);transitionTime_in processingStates.add(ps_ready); processingStates.add(ps_queued); where ProcessInstance = processingStates.add(ps_submitted)ProcessInstance_in; ELSIF processingStates.add(ps_running); = ProcessingStatus_in THEN processingStates.add(ps_success); processingStates.add(ps_failed); update ProcessInstance processingStates.add(ps_terminated); processingStates.add(ps_canceled); processingStates.add(ps_terminated); set StartDate = transitionTime_in processingStates.add(ps_skipped); } private static HashSetwhere finalProcessingStatesProcessInstance = new HashSet()ProcessInstance_in; static { ELSIF finalProcessingStates.add(ps_terminated); success = ProcessingStatus_in OR ps_failed = finalProcessingStates.add(ps_canceled); ProcessingStatus_in THEN finalProcessingStates.add(ps_success); finalProcessingStates.add(ps_failed);update ProcessInstance finalProcessingStates.add(ps_skipped); } private static HashSetset streamStatesEndDate = new HashSet();transitionTime_in static { streamStates.add(ss_waiting); streamStates.add(ss_queued); where ProcessInstance = ProcessInstance_in; streamStates.add(ss_running)END IF; streamStates.add(ss_success CheckProcessDependents(ProcessInstanceRow_out.Process, ProcessInstanceRow_out.Stream, ProcessingStatus_in); StreamStatus_out := streamStatesSP_STREAM.addcalculateStreamStatus(ssProcessInstanceRow_failedout.Stream); streamStates.add(ss_terminating); streamStates.add(ss_terminated); streamStates.add(ss_canceling); streamStates.add(ss_canceled); } private static HashSet finalStreamStates = new HashSet(); static {END; |
Code Block |
---|
public void setProcessInstanceStatus(int processInstance, ProcessingStatus newProcessingStatus, Timestamp transitionTime) throws InvalidStatusTransitionException, SQLException { CallableStatement stmt = connection.prepareCall("{call DATA_ACCESS.SetProcessInstanceStatus(?,?,?)}"); try finalStreamStates.add(ss_terminated); { finalStreamStates stmt.add(ss_canceledsetInt(1, processInstance); finalStreamStates.add(ss_success stmt.setString(2, newProcessingStatus.toString()); finalStreamStates.add(ss_failed stmt.setTimestamp(3, transitionTime); } private static boolean allComplete(Map procStatMap, Map streamStatMap) {stmt.execute(); } for (Iterator i = processingStates.iterator(); i.hasNext();)catch(SQLException x) { Stringint stateerrorCode = (String)i.nextx.getErrorCode(); intif count(errorCode = ((Integer)procStatMap.get(state)).intValue(); = InvalidStatusTransitionException.errorCode) ifthrow ( !finalProcessingStates.contains(state) && (count != 0) )new InvalidStatusTransitionException(x); else returnthrow falsex; } forfinally (Iterator i = streamStates.iterator(); i.hasNext();) { String state = (String)i.next();stmt.close(); } } |
Code Block |
---|
package org.glast.pipeline.server.sql.sp; public class SPStream { int count = ((Integer)streamStatMap.get(state)).intValue();// Package-specific Exception types: public static final int if ( !finalStreamStates.contains(state) && (count != 0) ) invalid_stream_ex = return false-20026; // ProcessingStatus Enumeration }Constants: public static final returnString true; } ps_waiting private static boolean all(String key, Map map) {= "WAITING"; public static final intString total = 0; ps_ready for= (Iterator i = map.values().iterator(); i.hasNext();) { "READY"; public static final String ps_queued total += ((Integer)i.next()).intValue()= "QUEUED"; public static final } String ps_submitted return ((Integer)map.get(key)).intValue() == total; } "SUBMITTED"; privatepublic static booleanfinal any(String key, Map map) { ps_running return ((Integer)map.get(key)).intValue() != 0; }"RUNNING"; public static final String calculateStreamStatus(int stream) throws ClassNotFoundException { ps_success = "SUCCESS"; String retValpublic = ss_waiting; static final String ps_failed Connection connection = null; // Database connection object "FAILED"; public static final ResultSetString rset = null; ps_terminated = int parentStream = 0"TERMINATED"; public static final tryString { ps_canceled // Get a= Default Database Connection using"CANCELED"; Server Side JDBCpublic Driver. static final String ps_skipped // Note : This class will= be loaded on the Database Server and hence use a "SKIPPED"; // StreamStatus Enumeration Constants: public static final String // Serverss_waiting Side JDBC Driver to= get default Connection to Database "WAITING"; public static final String if (System.getProperty("java.vendor").toLowerCase().indexOf("oracle") != -1) { ss_queued = "QUEUED"; public static final String // we're ss_running as a stored procedure,= connect locally: "RUNNING"; public static final String connection = DriverManager.getConnection("jdbc:default:connection"); ss_success = "SUCCESS"; } elsepublic { static final String ss_failed = // we're running outside the DB, connect via standard oracle jdbc driver: "FAILED"; public static final String ss_terminated = Class.forName("oracle.jdbc.driver.OracleDriver")"TERMINATED"; public static final String ss_canceled connection = DriverManager.getConnection("jdbc:oracle:thin:@glast-oracle02.slac.stanford.edu:1521:GLASTDEV","GLAST_DP_TEST","BT33%Q9]MU") "CANCELED"; public static final String } ss_terminating = // "TERMINATING"; public static final String ss_canceling // Get= information about current stream"CANCELING"; private static HashSet processingStates = // new HashSet(); static { String currentStatus processingStates.add(ps_waiting); processingStates.add(ps_ready); PreparedStatement stmt = connectionprocessingStates.prepareStatementadd(ps_queued); processingStates.add(ps_submitted); processingStates.add(ps_running); "select * " + processingStates.add(ps_success); processingStates.add(ps_failed); processingStates.add(ps_terminated); "from Stream " + processingStates.add(ps_canceled); processingStates.add(ps_terminated); "where Stream = ? "processingStates.add(ps_skipped); } private static HashSet finalProcessingStates = new HashSet(); static { stmtfinalProcessingStates.setInt(1,streamadd(ps_terminated); finalProcessingStates.add(ps_canceled); rset = stmtfinalProcessingStates.executeQueryadd(ps_success); // Execute the query, get Resultset finalProcessingStates.add(ps_failed); if (rset.next()) {finalProcessingStates.add(ps_skipped); } private static HashSet streamStates = currentStatus = rset.getString("STREAMSTATUS"new HashSet(); static { parentStream = rset.getInt("PARENTSTREAM"streamStates.add(ss_waiting); } else {streamStates.add(ss_queued); streamStates.add(ss_running); throw new SQLException("No such stream", "", invalid_stream_exstreamStates.add(ss_success); }streamStates.add(ss_failed); stmt.close(streamStates.add(ss_terminating); streamStates.add(ss_terminated); // streamStates.add(ss_canceling); // Get a count of the Processes in each state for this Stream: streamStates.add(ss_canceled); } private static HashSet finalStreamStates = new HashSet(); static { // finalStreamStates.add(ss_terminated); stmt = connection.prepareStatement(finalStreamStates.add(ss_canceled); finalStreamStates.add(ss_success); "select ProcessingStatus, count(ProcessingStatus) AS COUNT " +finalStreamStates.add(ss_failed); } private static boolean allComplete(Map procStatMap, Map streamStatMap) { "from ProcessInstancefor "(Iterator + i = processingStates.iterator(); i.hasNext();) { String "wherestate Stream = ? " +(String)i.next(); int count = ((Integer)procStatMap.get(state)).intValue(); "group by ProcessingStatus " if ( !finalProcessingStates.contains(state) && (count != 0) ) ); stmt.setInt(1,stream)return false; } rset for (Iterator i = stmtstreamStates.executeQueryiterator(); // Execute the query, get Resultseti.hasNext();) { MapString procStatCountsstate = new HashMap(String)i.next(); forint (Iteratorcount i = processingStates.iterator((); i.hasNextInteger)streamStatMap.get(state)).intValue();) if ( procStatCounts!finalStreamStates.putcontains((String)i.next(), new Integer(0));state) && (count != 0) ) while (rset.next()) { return false; } procStatCounts.put(rset.getString("PROCESSINGSTATUS"), new Integer(rset.getInt("COUNT")));return true; } private static boolean all(String key, Map map) }{ int total = stmt.close()0; for (Iterator i // = map.values().iterator(); i.hasNext();) { // Get atotal count of the sub-Streams in each state for this Stream:+= ((Integer)i.next()).intValue(); } return ((Integer)map.get(key)).intValue() == //total; } private static stmt = connection.prepareStatement( boolean any(String key, Map map) { return ((Integer)map.get(key)).intValue() != 0; "select StreamStatus, count(StreamStatus) AS COUNT " + } public static String calculateStreamStatus(int stream) throws ClassNotFoundException { String retVal = ss_waiting; "from Stream " + Connection connection = null; // Database connection object "whereResultSet ParentStreamrset = ?null; " + int parentStream = 0; try { "group by StreamStatus" // Get a Default Database Connection using Server Side JDBC );Driver. stmt.setInt(1, stream); rset = stmt.executeQuery(); // Note : This class will be loaded on the Database Server and hence use a Map subStreamStatCounts = new HashMap(); // Server Side JDBC Driver to get default Connection to Database for (Iterator i = streamStates.iterator(); i.hasNext();)if (System.getProperty("java.vendor").toLowerCase().indexOf("oracle") != -1) { subStreamStatCounts.put((String)i.next(), new Integer(0)); while (rset.next()) {// we're running as a stored procedure, connect locally: subStreamStatCounts.put(rset.getString("STREAMSTATUS"), new Integer(rset.getInt("COUNT")))connection = DriverManager.getConnection("jdbc:default:connection"); } else { stmt.close(); if (currentStatus == ss_terminating) { // we're running outside the DB, connect via standard oracle jdbc driver: if (allComplete(procStatCounts, subStreamStatCounts)) {Class.forName("oracle.jdbc.driver.OracleDriver"); retVal = ss_terminated; connection = DriverManager.getConnection("jdbc:oracle:thin:@glast-oracle02.slac.stanford.edu:1521:GLASTDEV","GLAST_DP_TEST","BT33%Q9]MU"); } } else { // // retVal = ss_terminating; Get information about current stream }// }String currentStatus; else if (currentStatus == ss_canceling) { PreparedStatement stmt = connection.prepareStatement( if (allComplete(procStatCounts, subStreamStatCounts)) { "select * " + retVal = ss_canceled; "from Stream " + } else { "where Stream = retVal = ss_canceling;? " } ); } else if ( any(ps_running, procStatCounts) || any(ss_running, subStreamStatCounts) stmt.setInt(1,stream); rset = stmt.executeQuery(); // Execute the query, get Resultset if (rset.next()) { retValcurrentStatus = ss_runningrset.getString("STREAMSTATUS"); } else parentStream if= rset.getInt( any(ps_queued, procStatCounts) || any(ps_submitted, procStatCounts) || any(ss_queued, subStreamStatCounts) )"PARENTSTREAM"); } else { retVal = ss_queued throw new SQLException("No such stream", "", invalid_stream_ex); } else if ( any(ps_waiting, procStatCounts) || any(ss_waiting, subStreamStatCounts) ) {stmt.close(); // retVal = ss_waiting; // Get a count }of elsethe ifProcesses ( any(ps_failed, procStatCounts) || any(ss_failed, subStreamStatCounts) ) {in each state for this Stream: // retValstmt = ss_failed;connection.prepareStatement( } else if ( all(ps_success, procStatCounts) && all(ss_success, subStreamStatCounts) ) {"select ProcessingStatus, count(ProcessingStatus) AS COUNT " + retVal = ss_success; "from ProcessInstance " + } "where stmtStream = connection.prepareStatement("update Stream set StreamStatus = ? where Stream = ?");? " + "group by ProcessingStatus " stmt.setString(1,retVal ); stmt.setInt(21,stream); rset = stmt.executeUpdateexecuteQuery(); // Execute the query, get Resultset if (parentStream != 0) Map procStatCounts = calculateStreamStatus(parentStreamnew HashMap(); } catchfor (SQLException ex) { // Trap SQL Errors Iterator i = processingStates.iterator(); i.hasNext();) procStatCounts.put((String)i.next(), new ex.printStackTraceInteger(0)); } finally while (rset.next()) { try{ if (connection != null || !connection.isClosed()) procStatCounts.put(rset.getString("PROCESSINGSTATUS"), new Integer(rset.getInt("COUNT"))); } connection stmt.close(); // Close the database connection // // } catch(SQLException ex){ Get a count of the sub-Streams in each state for this Stream: ex.printStackTrace();// stmt = connection.prepareStatement( } "select StreamStatus, count(StreamStatus) AS COUNT " + } "from return retVal;Stream " + } } |
Code Block |
---|
%ORACLE_HOME%\bin\loadjava -user=GLAST_DP_TEST/BT33%%Q9]MU@glast-oracle02.slac.stanford.edu:1521:GLASTDEV -verbose -force -resolve %project_base%\src\main\java\org\glast\pipeline\server\sql\sp\*.java
|
No Format |
---|
set CLASSPATH=%ORACLE_HOME%\sqlj\lib\translator.jar;%ORACLE_HOME%\sqlj\lib\runtime12.jar;%ORACLE_HOME%\jdbc\lib\ojdbc14.jar;%ORACLE_HOME%\sqlj\lib\utl_dbws.jar;%ORACLE_HOME%\jdbc\lib\orai18n.jar;%ORACLE_HOME%\sqlj\runtime12ee.jar;%ORACLE_HOME%\jpub\lib\jpub.jar;%ORACLE_HOME%\sqlj\lib\sqljutl.jar
%ORACLE_HOME%\bin\jpub -user=glast_dp_test/BT33%%Q9]MU -url=jdbc:oracle:thin:@glast-oracle02.slac.stanford.edu:1521:GLASTDEV -java=org.glast.pipeline.server.sql.sp.* -package=org.glast.pipeline.server.sql.spclient -compile=false -dir=%project_base%\src\main\java\
|
...
"where ParentStream = ? " +
"group by StreamStatus"
);
stmt.setInt(1, stream);
rset = stmt.executeQuery();
Map subStreamStatCounts = new HashMap();
for (Iterator i = streamStates.iterator(); i.hasNext();)
subStreamStatCounts.put((String)i.next(), new Integer(0));
while (rset.next()) {
subStreamStatCounts.put(rset.getString("STREAMSTATUS"), new Integer(rset.getInt("COUNT")));
}
stmt.close();
if (currentStatus == ss_terminating) {
if (allComplete(procStatCounts, subStreamStatCounts)) {
retVal = ss_terminated;
} else {
retVal = ss_terminating;
}
} else if (currentStatus == ss_canceling) {
if (allComplete(procStatCounts, subStreamStatCounts)) {
retVal = ss_canceled;
} else {
retVal = ss_canceling;
}
} else if ( any(ps_running, procStatCounts) || any(ss_running, subStreamStatCounts) ) {
retVal = ss_running;
} else if ( any(ps_queued, procStatCounts) || any(ps_submitted, procStatCounts) || any(ss_queued, subStreamStatCounts) ) {
retVal = ss_queued;
} else if ( any(ps_waiting, procStatCounts) || any(ss_waiting, subStreamStatCounts) ) {
retVal = ss_waiting;
} else if ( any(ps_failed, procStatCounts) || any(ss_failed, subStreamStatCounts) ) {
retVal = ss_failed;
} else if ( all(ps_success, procStatCounts) && all(ss_success, subStreamStatCounts) ) {
retVal = ss_success;
}
stmt = connection.prepareStatement("update Stream set StreamStatus = ? where Stream = ?");
stmt.setString(1,retVal);
stmt.setInt(2,stream);
stmt.executeUpdate();
if (parentStream != 0)
calculateStreamStatus(parentStream);
} 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();
}
}
return retVal;
}
}
|
Loading Java:
Code Block |
---|
%ORACLE_HOME%\bin\loadjava -user=GLAST_DP_TEST/BT33%%Q9]MU@glast-oracle02.slac.stanford.edu:1521:GLASTDEV -verbose -force -resolve %project_base%\src\main\java\org\glast\pipeline\server\sql\sp\*.java
|
Dropping Java:
Code Block |
---|
%ORACLE_HOME%\bin\dropjava -user "GLAST_DP_TEST/BT33%Q9]MU@glast-oracle02.slac.stanford.edu:1521:GLASTDEV" -verbose org.glast.pipeline.server.sql.sp.OraEnv
|
Publishing (previously loaded) Java:
No Format |
---|
set CLASSPATH=%ORACLE_HOME%\sqlj\lib\translator.jar;%ORACLE_HOME%\sqlj\lib\runtime12.jar;%ORACLE_HOME%\jdbc\lib\ojdbc14.jar;%ORACLE_HOME%\sqlj\lib\utl_dbws.jar;%ORACLE_HOME%\jdbc\lib\orai18n.jar;%ORACLE_HOME%\sqlj\runtime12ee.jar;%ORACLE_HOME%\jpub\lib\jpub.jar;%ORACLE_HOME%\sqlj\lib\sqljutl.jar
%ORACLE_HOME%\bin\jpub -user=glast_dp_test/BT33%%Q9]MU -url=jdbc:oracle:thin:@glast-oracle02.slac.stanford.edu:1521:GLASTDEV -java=org.glast.pipeline.server.sql.sp.* -package=org.glast.pipeline.server.sql.spclient -compile=false -dir=%project_base%\src\main\java\
|
Code Block |
---|
package org.glast.pipeline.server.sql.spclient;
public class SPStream
{
public SPStream(java.sql.Connection conn) throws java.sql.SQLException
{ m_ctx = new sqlj.runtime.ref.DefaultContext(conn); }
// MORE GENERATED CODE HERE <clipped> public java.lang.String calculateStreamStatus(int p0)
throws java.lang.ClassNotFoundException
{
Object __jRt_0 = null;
try {
__jRt_0 = oracle.jpub.reflect.Client.invoke(_context(),null, "org.glast.pipeline.server.sql.sp.SPStream","calculateStreamStatus","I",new Object[]{new java.lang.Integer(p0)});
}
catch (java.lang.ClassNotFoundException e) {
throw e;
}
catch (Throwable e) {
e.printStackTrace();
}
return (java.lang.String)__jRt_0;
}
}
|
Code Block |
---|
CREATE OR REPLACE PACKAGE SP_STREAM
AS
-- Package-specific types:
TYPE CURSOR IS REF CURSOR;
-- public static String calculateStreamStatus(int stream)
FUNCTION calculateStreamStatus(Stream_in IN number) RETURN varchar2;
END SP_STREAM;
/
CREATE OR REPLACE PACKAGE BODY SP_STREAM
AS
FUNCTION calculateStreamStatus(Stream_in IN number) RETURN varchar2 IS
LANGUAGE JAVA
NAME 'org.glast.pipeline.server.sql.sp.SPStream.calculateStreamStatus(int) return java.lang.String';
END SP_STREAM;
/
|
a