实施 Java 存储过程 IBM DB2 for i (AS400)
Implementing Java stored procedure IBM DB2 for i (AS400)
我创建了 Java 存储过程如下,能够使用 AS400 Qshell 命令解释器生成 .class
文件。
import java.sql.*;
public class sample
{
public sample(){
super();
}
/**
* @param args
*/
public static void Test(int test) throws SQLException, Exception {
// TODO Auto-generated method stub
try
{ Class.forName ("com.ibm.as400.access.AS400JDBCDriver").newInstance ();
String url = "jdbc:as400://ilava;naming=system;prompt=false;user=IPGUI;password=IPGUI;libraries=IPSRFILI,IPTSFILI,IPWMFILI,IPPAFILI,IPASFILI,IPSAFILI,IPTSUTL;translate binary=true";
Connection con = DriverManager.getConnection(url);
PreparedStatement ps = con.prepareStatement("INSERT INTO IPTSFILI.TEMP VALUES ('IP', 'WELCOME TO SQLJ')");
ps.executeUpdate();
ps.close();
con.close();
}
catch (Exception e)
{
System.out.println (e);
System.exit(1);
}
}
}
创建了相应的存储过程
CREATE procedure IPTSFILI.SPSAMPLE (
IN TEST INTEGER )
LANGUAGE JAVA
SPECIFIC IPTSFILI.SPSAMPLE
DETERMINISTIC
MODIFIES SQL DATA
CALLED ON NULL INPUT
EXTERNAL NAME 'sample!Test'
PARAMETER STYLE JAVA ;
调用过程时(使用 JAVA 中的可调用语句)它给出以下错误
java.sql.SQLException: [SQL4304] Java stored procedure or user-defined function SPSAMPLE, specific name SPSAMPLE could not load Java class Ä?_ÑÂ_À¦ÀÂÄ/øøàâàÊÑÎÁÊ for reason code 3.
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:687)
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:653)
at com.ibm.as400.access.AS400JDBCStatement.commonExecute(AS400JDBCStatement.java:920)
at com.ibm.as400.access.AS400JDBCPreparedStatement.execute(AS400JDBCPreparedStatement.java:1018)
at Exec.main(Exec.java:23)
将 .class
文件放入 QIBM\UserData\OS400\SQLLib\Function
目录。
关于如何解决这个问题有什么建议吗?
您可能没有以正确的方式指定过程。查看 OS400 and Java stored proc (see Chap 7) 的文档,我认为您在这里缺少几个步骤。我建议从文档中获取代码并运行它,然后替换为您自己的实现。
您的 Java 代码有一些问题。
您不应在 Java 存储过程中使用 System.out。由于系统的性质,如果在回收的 QZDASOINIT 或 QSQSRVR 作业中调用 Java 存储过程,System.out 将无法正常工作。
您不应在通话中使用 System.exit(1)。该调用将结束 JVM,一旦 JVM 结束,就无法重新启动。
如果要访问定义了 Java 存储过程的同一系统上的表,您可能应该使用本机 JDBC 驱动程序。要获得使用本机驱动程序的 JDBC 连接,您应该调用 DriverManager.getConnection("jdbc:default:connection");
如果您没有捕获异常,如果您使用 JDBC 客户端调用存储过程,大多数 JDBC 异常将正确返回。
我将程序更新为如下所示。
import java.sql.*;
public class sample
{
public sample(){
super();
}
/**
* @param args
*/
public static void Test(int test) throws SQLException, Exception {
String url = "jdbc:default:connection";
Connection con = DriverManager.getConnection(url);
PreparedStatement ps = con.prepareStatement("INSERT INTO IPTSFILI.TEMP VALUES ('IP', 'WELCOME TO SQLJ')");
ps.executeUpdate();
ps.close();
con.close();
}
}
当我调用它时,出现以下异常(因为我没有在我的系统上创建该文件)。
SQLState: 42704
Message: [SQL0204] TEMP in IPTSFILI type *FILE not found.
Vendor: -204
您还需要检查数据库服务器作业的 JOB CCSID 是否不是 65535。如果您的 JOB CCSID 是 65535,您应该会收到以下错误,但我怀疑早于 6.1 的版本可能没有检测到这个正确。
CALL QSYS.QCMDEXC('Chgjob ccsid(65535) ',000000020.00000)
call SPSAMPLE(3)
*** SQLException caught ***
Statement was call SPSAMPLE(3)
SQLState: 57017
Message: [SQL0332] Character conversion between CCSID 65535 and CCSID 1200 not valid.
Vendor: -332
我创建了 Java 存储过程如下,能够使用 AS400 Qshell 命令解释器生成 .class
文件。
import java.sql.*;
public class sample
{
public sample(){
super();
}
/**
* @param args
*/
public static void Test(int test) throws SQLException, Exception {
// TODO Auto-generated method stub
try
{ Class.forName ("com.ibm.as400.access.AS400JDBCDriver").newInstance ();
String url = "jdbc:as400://ilava;naming=system;prompt=false;user=IPGUI;password=IPGUI;libraries=IPSRFILI,IPTSFILI,IPWMFILI,IPPAFILI,IPASFILI,IPSAFILI,IPTSUTL;translate binary=true";
Connection con = DriverManager.getConnection(url);
PreparedStatement ps = con.prepareStatement("INSERT INTO IPTSFILI.TEMP VALUES ('IP', 'WELCOME TO SQLJ')");
ps.executeUpdate();
ps.close();
con.close();
}
catch (Exception e)
{
System.out.println (e);
System.exit(1);
}
}
}
创建了相应的存储过程
CREATE procedure IPTSFILI.SPSAMPLE (
IN TEST INTEGER )
LANGUAGE JAVA
SPECIFIC IPTSFILI.SPSAMPLE
DETERMINISTIC
MODIFIES SQL DATA
CALLED ON NULL INPUT
EXTERNAL NAME 'sample!Test'
PARAMETER STYLE JAVA ;
调用过程时(使用 JAVA 中的可调用语句)它给出以下错误
java.sql.SQLException: [SQL4304] Java stored procedure or user-defined function SPSAMPLE, specific name SPSAMPLE could not load Java class Ä?_ÑÂ_À¦ÀÂÄ/øøàâàÊÑÎÁÊ for reason code 3.
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:687)
at com.ibm.as400.access.JDError.throwSQLException(JDError.java:653)
at com.ibm.as400.access.AS400JDBCStatement.commonExecute(AS400JDBCStatement.java:920)
at com.ibm.as400.access.AS400JDBCPreparedStatement.execute(AS400JDBCPreparedStatement.java:1018)
at Exec.main(Exec.java:23)
将 .class
文件放入 QIBM\UserData\OS400\SQLLib\Function
目录。
关于如何解决这个问题有什么建议吗?
您可能没有以正确的方式指定过程。查看 OS400 and Java stored proc (see Chap 7) 的文档,我认为您在这里缺少几个步骤。我建议从文档中获取代码并运行它,然后替换为您自己的实现。
您的 Java 代码有一些问题。
您不应在 Java 存储过程中使用 System.out。由于系统的性质,如果在回收的 QZDASOINIT 或 QSQSRVR 作业中调用 Java 存储过程,System.out 将无法正常工作。
您不应在通话中使用 System.exit(1)。该调用将结束 JVM,一旦 JVM 结束,就无法重新启动。
如果要访问定义了 Java 存储过程的同一系统上的表,您可能应该使用本机 JDBC 驱动程序。要获得使用本机驱动程序的 JDBC 连接,您应该调用 DriverManager.getConnection("jdbc:default:connection");
如果您没有捕获异常,如果您使用 JDBC 客户端调用存储过程,大多数 JDBC 异常将正确返回。
我将程序更新为如下所示。
import java.sql.*;
public class sample
{
public sample(){
super();
}
/**
* @param args
*/
public static void Test(int test) throws SQLException, Exception {
String url = "jdbc:default:connection";
Connection con = DriverManager.getConnection(url);
PreparedStatement ps = con.prepareStatement("INSERT INTO IPTSFILI.TEMP VALUES ('IP', 'WELCOME TO SQLJ')");
ps.executeUpdate();
ps.close();
con.close();
}
}
当我调用它时,出现以下异常(因为我没有在我的系统上创建该文件)。
SQLState: 42704
Message: [SQL0204] TEMP in IPTSFILI type *FILE not found.
Vendor: -204
您还需要检查数据库服务器作业的 JOB CCSID 是否不是 65535。如果您的 JOB CCSID 是 65535,您应该会收到以下错误,但我怀疑早于 6.1 的版本可能没有检测到这个正确。
CALL QSYS.QCMDEXC('Chgjob ccsid(65535) ',000000020.00000)
call SPSAMPLE(3)
*** SQLException caught ***
Statement was call SPSAMPLE(3)
SQLState: 57017
Message: [SQL0332] Character conversion between CCSID 65535 and CCSID 1200 not valid.
Vendor: -332