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 |
---|
public class SPStream { // Package-specific Exception types: public static final intPROCEDURE SetProcessInstanceStatus(ProcessInstance_in IN int, ProcessingStatus_in IN VARCHAR2, transitionTime_in IN TimeStamp) IS invalidProcessInstanceRow_stream_ex 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 = "RUNNING";from Process public static final String ps_success where Process = "SUCCESS"; ProcessInstanceRow_out.Process; public static final String IF 0 = ps_failed =GetStateTransitionValid(ProcessInstanceRow_out.ProcessingStatus, ProcessingStatus_in, ProcessType_out) THEN "FAILED"; public static final String ps_terminatedRAISE_APPLICATION_ERROR(invalid_status_transition_ex, = "TERMINATED"; public static final'Not Stringa valid state transition ps_canceledfrom ' || = "CANCELED"; public static final String ps_skippedProcessInstanceRow_out.ProcessingStatus || = "SKIPPED"; // StreamStatus Enumeration Constants: ' to public' static|| final String ss_waiting = "WAITING"; public static final StringProcessingStatus_in || ss_queued = "QUEUED"; ' for publica staticprocess finalof Stringtype ' || ss_running = "RUNNING"; public static final String ProcessType_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 = "TERMINATING"ProcessInstance_in; public static final String IF ps_submitted = ssProcessingStatus_cancelingin THEN = "CANCELING"; private static HashSetupdate processingStatesProcessInstance = new HashSet(); static { processingStates.add(ps_waiting); set SubmitDate = processingStates.add(ps_ready); transitionTime_in processingStates.add(ps_queued); where ProcessInstance = processingStates.add(ps_submitted)ProcessInstance_in; processingStates.add( ELSIF ps_running); = ProcessingStatus_in THEN processingStates.add(ps_success); processingStates.add(ps_failed);update ProcessInstance processingStates.add(ps_terminated); processingStates.add(ps_canceled); set StartDate = processingStates.add(ps_terminated); 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) where ProcessInstance = ProcessInstance_in; streamStates.add(ss_queued) END IF; streamStates.add(ss_running CheckProcessDependents(ProcessInstanceRow_out.Process, ProcessInstanceRow_out.Stream, ProcessingStatus_in); StreamStatus_out := streamStatesSP_STREAM.addcalculateStreamStatus(ssProcessInstanceRow_successout.Stream); streamStates.add(ss_failed); streamStates.add(ss_terminating); streamStates.add(ss_terminated);END; |
Code Block |
---|
public void setProcessInstanceStatus(int processInstance, ProcessingStatus newProcessingStatus, Timestamp transitionTime) throws InvalidStatusTransitionException, SQLException { streamStates.add(ss_canceling); streamStates.add(ss_canceled); } CallableStatement stmt = connection.prepareCall("{call DATA_ACCESS.SetProcessInstanceStatus(?,?,?)}"); try { private static HashSet finalStreamStates = new HashSet(stmt.setInt(1, processInstance); static { finalStreamStates.add(ss_terminatedstmt.setString(2, newProcessingStatus.toString()); finalStreamStatesstmt.add(ss_canceledsetTimestamp(3, transitionTime); finalStreamStates stmt.addexecute(ss_success); finalStreamStates.add(ss_failed);} } private static boolean allComplete(Map procStatMap, Map streamStatMap)catch(SQLException x) { for (Iteratorint ierrorCode = processingStates.iterator(); i.hasNextx.getErrorCode();) { Stringif state(errorCode == (String)i.next();InvalidStatusTransitionException.errorCode) int count throw =new ((Integer)procStatMap.get(state)).intValue(InvalidStatusTransitionException(x); if ( !finalProcessingStates.contains(state) && (count != 0) )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 { // Package-specific Exception types: public static final int invalid_stream_ex int count = ((Integer)streamStatMap.get(state)).intValue(); if ( !finalStreamStates.contains(state) && (count != 0) ) return false; = }-20026; // ProcessingStatus return true; } Enumeration Constants: privatepublic static booleanfinal all(String key, Map map) { ps_waiting = int total = 0"WAITING"; public static for (Iterator i = map.values().iterator(); i.hasNext();) {final String ps_ready = "READY"; public static final String total += ((Integer)i.next()).intValue(); ps_queued = } "QUEUED"; public return ((Integer)map.get(key)).intValue() == total; } static final String ps_submitted = "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"CANCELED"; using Server Sidepublic JDBCstatic Driver. 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 ss_waiting // Server Side JDBC= Driver to get default"WAITING"; Connection to Database public static final String ss_queued if (System.getProperty("java.vendor").toLowerCase().indexOf("oracle") != -1) { "QUEUED"; public static final String ss_running // we're running as a stored procedure, connect locally: = "RUNNING"; public static final String ss_success = connection = DriverManager.getConnection("jdbc:default:connection")"SUCCESS"; public static final String } elsess_failed { = "FAILED"; public static // we're running outside the DB, connect via standard oracle jdbc driver: final String ss_terminated = "TERMINATED"; public static final String ss_canceled = Class.forName("oracle.jdbc.driver.OracleDriver")"CANCELED"; public static final String ss_terminating connection = DriverManager.getConnection("jdbc:oracle:thin:@glast-oracle02.slac.stanford.edu:1521:GLASTDEV","GLAST_DP_TEST","BT33%Q9]MU"); "TERMINATING"; public static final String ss_canceling = }"CANCELING"; private static HashSet processingStates = //new HashSet(); static { // Get information about current stream processingStates.add(ps_waiting); processingStates.add(ps_ready); // processingStates.add(ps_queued); String currentStatusprocessingStates.add(ps_submitted); processingStates.add(ps_running); PreparedStatement stmt = connectionprocessingStates.prepareStatementadd(ps_success); processingStates.add(ps_failed); "select * " +processingStates.add(ps_terminated); processingStates.add(ps_canceled); processingStates.add(ps_terminated); "from Stream " + processingStates.add(ps_skipped); } private static HashSet finalProcessingStates = new HashSet(); "where Stream = ? "static { finalProcessingStates.add(ps_terminated); finalProcessingStates.add(ps_canceled); stmt.setInt(1,streamfinalProcessingStates.add(ps_success); finalProcessingStates.add(ps_failed); rset = stmtfinalProcessingStates.executeQueryadd(ps_skipped); // Execute the query, get Resultset } private static HashSet streamStates = new if (rset.next()) {HashSet(); static { currentStatus = rset.getString("STREAMSTATUS"streamStates.add(ss_waiting); streamStates.add(ss_queued); parentStream = rset.getInt("PARENTSTREAM"streamStates.add(ss_running); streamStates.add(ss_success); } else { streamStates.add(ss_failed); streamStates.add(ss_terminating); throw new SQLException("No such stream", "", invalid_stream_ex streamStates.add(ss_terminated); streamStates.add(ss_canceling); streamStates.add(ss_canceled); } private static HashSet finalStreamStates = new stmt.closeHashSet(); //static { finalStreamStates.add(ss_terminated); // Get a count of the Processes in each state for this Stream: finalStreamStates.add(ss_canceled); finalStreamStates.add(ss_success); finalStreamStates.add(ss_failed); //} private static boolean allComplete(Map procStatMap, Map stmtstreamStatMap) { = connection.prepareStatement( for (Iterator i = processingStates.iterator(); i.hasNext();) { "select ProcessingStatus, count(ProcessingStatus) ASString COUNTstate " += (String)i.next(); int count = ((Integer)procStatMap.get(state)).intValue(); "from ProcessInstance " + if ( !finalProcessingStates.contains(state) && (count != 0) ) "where Stream = ? " + return false; } "groupfor by(Iterator ProcessingStatusi " = streamStates.iterator(); i.hasNext();) { String state = (String)i.next(); stmt.setInt(1,streamint count = ((Integer)streamStatMap.get(state)).intValue(); rsetif =( stmt!finalStreamStates.executeQuerycontains(state); // Execute the query, get Resultset&& (count != 0) ) Map procStatCounts = newreturn HashMap()false; } for (Iterator i = processingStates.iterator(); i.hasNext();) return true; } private static boolean all(String key, Map map) { procStatCounts.put((String)i.next(), new Integer(0))int total = 0; for (Iterator i while (rset.next()= map.values().iterator(); i.hasNext();) { total procStatCounts.put(rset.getString("PROCESSINGSTATUS"), new Integer(rset.getInt("COUNT"))); += ((Integer)i.next()).intValue(); } stmt.close(); // return ((Integer)map.get(key)).intValue() == total; } private static boolean any(String key, Map map) { // Get a count of the sub-Streams in each state for this Stream: return ((Integer)map.get(key)).intValue() != 0; } public static String calculateStreamStatus(int stream) throws ClassNotFoundException { // String retVal = ss_waiting; stmt =Connection connection.prepareStatement( = null; // Database connection object ResultSet rset = "select StreamStatus, count(StreamStatus) AS COUNT " + null; int parentStream = 0; try { "from Stream " + // Get a Default Database Connection using Server Side JDBC Driver. "where ParentStream = ? " + // Note : This class will be loaded on the Database Server and hence use "groupa by StreamStatus" // Server Side JDBC Driver to get ); default Connection to Database stmt.setInt(1, stream);if (System.getProperty("java.vendor").toLowerCase().indexOf("oracle") != -1) { rset = stmt.executeQuery(); Map subStreamStatCounts = new HashMap(); // we're running as a stored procedure, connect locally: for (Iterator i connection = streamStatesDriverManager.iterator(); i.hasNext();)getConnection("jdbc:default:connection"); } else subStreamStatCounts.put((String)i.next(), new Integer(0)); { while (rset.next()) { subStreamStatCounts.put(rset.getString("STREAMSTATUS"), new Integer(rset.getInt("COUNT")));// we're running outside the DB, connect via standard oracle jdbc driver: } stmt.close(Class.forName("oracle.jdbc.driver.OracleDriver"); if (currentStatus connection == ss_terminating) { DriverManager.getConnection("jdbc:oracle:thin:@glast-oracle02.slac.stanford.edu:1521:GLASTDEV","GLAST_DP_TEST","BT33%Q9]MU"); } if (allComplete(procStatCounts, subStreamStatCounts)) {// // Get information about current retValstream = ss_terminated; // } elseString {currentStatus; PreparedStatement stmt = connection.prepareStatement( retVal = ss_terminating; "select * " }+ } else if (currentStatus == ss_canceling) { "from Stream " + if (allComplete(procStatCounts, subStreamStatCounts)) { "where Stream = ? " retVal = ss_canceled; ); } else { stmt.setInt(1,stream); rset = stmt.executeQuery(); // Execute the retValquery, = ss_canceling;get Resultset if (rset.next()) { } } else ifcurrentStatus (= any(ps_running, procStatCounts) || any(ss_running, subStreamStatCounts) ) {rset.getString("STREAMSTATUS"); retValparentStream = ss_runningrset.getInt("PARENTSTREAM"); } else if{ ( any(ps_queued, procStatCounts) || any(ps_submitted, procStatCounts) || any(ss_queued, subStreamStatCounts) ) { throw new SQLException("No such stream", retVal = ss_queued"", invalid_stream_ex); } else if ( any(ps_waiting, procStatCounts) || any(ss_waiting, subStreamStatCounts) stmt.close(); { // retVal = ss_waiting; // Get a count of }the elseProcesses ifin ( any(ps_failed, procStatCounts) || any(ss_failed, subStreamStatCounts) ) { 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, if (parentStream != 0) get Resultset Map procStatCounts = new calculateStreamStatusHashMap(parentStream); } catchfor (SQLExceptionIterator ex)i { // Trap SQL Errors ex.printStackTrace= processingStates.iterator(); i.hasNext();) } finally { procStatCounts.put((String)i.next(), new Integer(0)); trywhile (rset.next()) { if (connection != null || !connection.isClosed())procStatCounts.put(rset.getString("PROCESSINGSTATUS"), new Integer(rset.getInt("COUNT"))); } connectionstmt.close(); // Close the database connection // Get a count of the } catch(SQLException ex){ sub-Streams in each state for this Stream: ex.printStackTrace();// stmt }= connection.prepareStatement( } return retVal; } } |
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
|
"select StreamStatus, count(StreamStatus) AS COUNT " +
"from Stream " +
"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 ' |
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\ .SPStream.calculateStreamStatus(int) return java.lang.String'; END SP_STREAM; / |
a