[英]SQL4306N Java stored procedure or user-defined function could not call Java method
We just upgraded to DB2 10.5 from 9.5, this process was working fine until the upgrade was performed on the server.我们刚刚从 9.5 升级到 DB2 10.5,这个过程运行良好,直到在服务器上执行升级。 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!当我从 linux 服务器运行 jar 文件时,出现以下错误但是当我在 Windows 计算机上从 eclipse 运行完全相同的代码时,它工作得很好! I am also getting a similar error if I calll this sp from DB2 control center.如果我从 DB2 控制中心调用这个 sp,我也会收到类似的错误。 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". SQL4306N Java 存储过程或用户定义函数“ESADBM.GETNEXTID”,特定名称“WHDBRMM_UTILS”无法调用Java 方法“GetNextID”,签名“(Ljava/lang/String;[I)V”。 SQLSTATE=42724 SQLSTATE=42724
Explanation:说明:
The Java method given by the EXTERNAL NAME clause of a CREATE PROCEDURE or CREATE FUNCTION statement could not be found.找不到由 CREATE PROCEDURE 或 CREATE FUNCTION 语句的 EXTERNAL NAME 子句给出的 Java 方法。 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.确保存在带有“public”标志和此调用的预期参数列表的 Java 实例方法。
sqlcode: -4306 sqlcode:-4306
sqlstate: 42724. 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.外部例程的库,包括 Java 类和 Java 例程的 JAR 文件,必须存在于 DB2 实例目录中的某个位置。 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).当您升级 DB2 版本时,会创建一个新实例,但不会自动复制这些库(顺便说一下,这是有道理的,因为它们很有可能需要重建)。
The error message indicates that the instance cannot find the Java class file that implements GETNEXTID
-- that would be DBSequence.class
.该错误消息表明该实例无法找到实现GETNEXTID
的 Java 类文件——即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 .该类需要复制到数据库服务器上 DB2 10.5 实例主目录中的sqllib/function
目录,如手册中所述。 You will probably need also to create pkgUtil_v4_0_0_0
under sqllib/function
for the correct package structure.您可能还需要在sqllib/function
下创建pkgUtil_v4_0_0_0
以获得正确的包结构。 Make sure you compile the Java source using the same JDK version as the one used by the DB2 instance to run the program.确保使用与 DB2 实例运行程序所用的 JDK 版本相同的 JDK 版本来编译 Java 源代码。
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.完成此操作后,在您选择的 DB2 客户端中执行CALL SQLJ.REFRESH_CLASSES()
以确保 DB2 重新加载最新版本。 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.话虽如此,我真的不明白您为什么使用如此复杂的方式来检索 SQL 序列值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.