We just upgraded to DB2 10.5 from 9.5, this process was working fine until the upgrade was performed on the server. When i run the jar file from a linux server, I get the following error however when i run the exact same code from eclipse on my windows computer, it works just fine! I am also getting a similar error if I calll this sp from DB2 control center. I am looking to know what is causing this and how can i fix this error?
SQL4306N Java stored procedure or user-defined function "ESADBM.GETNEXTID", specific name "WHDBRMM_UTILS" could not call Java method "GetNextID", signature "(Ljava/lang/String;[I)V". SQLSTATE=42724
Explanation:
The Java method given by the EXTERNAL NAME clause of a CREATE PROCEDURE or CREATE FUNCTION statement could not be found. Its declared argument list may not match what the database expects, or it may not be a "public" instance method.
User response:
Ensure that a Java instance method exists with the "public" flag and the expected argument list for this call.
sqlcode: -4306
sqlstate: 42724.
Here is the code:
package pkgUtil_v4_0_0_0;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.hibernate.exception.JDBCConnectionException;
public class DBSequence {
public static final String SEQ_CONTACTID = "ContactIDSeq";
public static final String SEQ_PROJECTID = "ProjectIDSeq";
public static final String SEQ_LOCATIONID = "LocationIDSeq";
public static final String SEQ_SOURCEID = "SourceIDSeq";
public static final String SEQ_SURVEYID = "SurveyIDSeq";
public static final String SEQ_LOGICALSURVEYID = "WageAreaIDSeq";
public static final String SEQ_WAGEDETAILID = "WageDetailIDSeq";
public static final String SEQ_ORGID = "OrgIDSeq";
public static final String SEQ_OFFICEID = "RegionNumberSeq";
public static final String SEQ_LETTERID = "LetterIDSeq";
public static final String SEQ_DODGEID = "DodgeIDSeq";
public static final String SEQ_CRAFTID = "CraftIDSeq";
public static final String SEQ_CRAFTTITLEID = "CraftTitleIDSeq";
public static final String SEQ_ANALYSTID = "AnalystIDSeq";
public static final String SEQ_LETTERTEMPLATEID = "LetterTemplateIDSeq";
public static final String SEQ_RECRATESID = "RecRatesIDSeq";
public static final String SEQ_BRIDGESCDID = "BridgeSCDIDSeq";
public static String drvr = "";
public static Connection con = null;
// utility function
public static int getNextId(Connection lcon, String sequence) throws SQLException {
Boolean bFlag;
PreparedStatement stmt = null;
int id = 0;
String sql = "select next value for esadbm." +
sequence + " from SYSIBM.sysdummy1";
// System.out.println("String = "+sequence);
stmt = lcon.prepareStatement(sql);
ResultSet resultSet = stmt.executeQuery();
if (resultSet.next()) {
id = resultSet.getInt(1);
}
resultSet.close();
stmt.close();
return id;
}
// Stored Procedure Entry Point
public static void getNextId(String sequence, int[] seq) throws SQLException, Exception {
System.out.println("String = "+sequence);
System.out.println("Array = "+seq);
if (drvr.length() == 0) {
drvr = "jdbc:default:connection";
con = DriverManager.getConnection(drvr);
}
drvr = "";
seq[0] = getNextId(con, sequence);
con.close();
}
// test procedure
public static void main(String args[])throws SQLException, Exception {
try {
System.out.println("Connecting to DB " + args[0]);
Class.forName("com.ibm.db2.jcc.DB2Driver");
drvr = "jdbc:db2:" + args[0];
// System.out.println(drvr+args[1] + args[2]);
con = DriverManager.getConnection("jdbc:db2:" + args[0], args[1],args[2]);
// System.out.println(con);
System.out.println("DB Connection Successful");
con = DriverManager.getConnection(drvr, args[1], args[2]);
Statement st = con.createStatement();
String query = "set schema = 'ESADBM'";
st.execute(query);
System.out.println("Getting ID");
int id = getNextId(con, SEQ_SOURCEID);
System.out.println("Returned : " + Integer.toString(id));
}
catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
catch (SQLException sqle) {
sqle.printStackTrace();
}
catch (JDBCConnectionException e) {
System.out.println("Unable to connect to database");
e.printStackTrace();
}
}
}
Here is the stored procedure:
CREATE PROCEDURE "ESADBM "."GETNEXTID"
(
IN SEQUENCE CHARACTER(40),
OUT ID INTEGER
)
DYNAMIC RESULT SETS 0
SPECIFIC WHDBRA_UTILS
EXTERNAL NAME 'pkgUtil_v4_0_0_0.DBSequence!getNextId()'
LANGUAGE JAVA
PARAMETER STYLE JAVA
NOT DETERMINISTIC
FENCED THREADSAFE
MODIFIES SQL DATA
NO DBINFO;
Libraries for external routines, including Java classes and JAR files for Java routines, must be present in a certain location in the DB2 instance directory. When you upgrade your DB2 version, a new instance is created, but those libraries are not copied automatically (which, by the way, makes sense as there is a good chance that they need to be rebuilt).
The error message indicates that the instance cannot find the Java class file that implements GETNEXTID
-- that would be DBSequence.class
. The class needs to be copied to the sqllib/function
directory in the DB2 10.5 instance home on the database server, as explained in the manual . You will probably need also to create pkgUtil_v4_0_0_0
under sqllib/function
for the correct package structure. Make sure you compile the Java source using the same JDK version as the one used by the DB2 instance to run the program.
Once you do that, execute CALL SQLJ.REFRESH_CLASSES()
in the DB2 client of your choice to make sure DB2 reloads the most current version. After that your stored procedure should work correctly.
Having said that, I don't really understand why you use such a convoluted way of retrieving a SQL sequence value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.