实现 Java 存储过程 IBM DB2 for i (AS400)
Posted
技术标签:
【中文标题】实现 Java 存储过程 IBM DB2 for i (AS400)【英文标题】:Implementing Java stored procedure IBM DB2 for i (AS400) 【发布时间】:2015-04-07 09:08:28 【问题描述】:我创建的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 中使用 callable 语句)时,它会给出以下错误
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
目录中。
关于如何解决这个问题的任何建议?
【问题讨论】:
你在哪里调用存储过程?在您的代码中看不到它。此外,提供完整的堆栈跟踪会有所帮助 @Ortis,更新了堆栈跟踪。 @AntoKris 类应该实现COM.ibm.db2.app.StoredProc
接口吧?你可以试试看会发生什么
看起来像是编码问题,您是如何创建存储过程的?您可以尝试使用 iSeries 访问重新创建它吗?
【参考方案1】:
您可能没有以正确的方式指定程序。查看OS400 和Java stored proc (see Chap 7) 的文档,我认为您在这里缺少几个步骤。我建议从文档中获取代码并运行它,然后替换为您自己的实现。
【讨论】:
我按照第 7 章中提到的步骤进行操作,但仍然遇到与“ [SQL4304] Java 存储过程或用户定义函数 SPSAMPLE,特定名称 SPSAMPLE 无法加载 Java 类 Ä?_ÑÂ_À¦ ÀÂÄ/øøàâàÊÑÎÁÊ 原因代码为 3。“您能建议摆脱这种情况的方法吗? 你试过运行这个例子吗?如果有效,您可以排除编码问题。 我试过同样的教程,但是我错过了对java程序“CRTJVAPGM CLSF(Db2CusInCity.class) OPTIMIZE(40)”的优化。有必要吗?【参考方案2】:您的 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
【讨论】:
感谢您的回复。我尝试了您建议的方式,但收到错误为 SQL 状态:42724 供应商代码:-4304 消息:[SQL4304] Java 存储过程或用户定义函数 SPSAMPLE,特定名称 SPSAMPLE 无法加载 Java 类 Ä?_ÑÂ_À¦ÀÂÄ/øøàâàÊÑÎÁÊ原因码 3。 @AntoKris 您使用的是什么 IBM i 版本?您可以删除该过程并改用此创建语句吗? CREATE 过程 IPTSFILI.SPSAMPLE ( IN TEST INTEGER ) 语言 JAVA 参数样式 JAVA 确定性修改 SQL 数据调用 NULL 输入外部名称 'sample.Test' 7.1版。感谢您的回复。 收到类似消息的错误:[SQL4304] Java 存储过程或用户定义函数 MYJAVASTOREPROC,特定名称 MYJAVASTOREPROC 无法加载 Java 类 SP,原因代码为 1。1 -- 找不到该类类路径。 执行以下工作: --- 创建函数 getProperty(key varchar(200)) 返回 varchar(1024) 语言 java 参数样式 java 外部名称 'java.lang.System.getProperty' -- 然后--- select getProperty('java.home') from sysibm.sysdummy1 -- 在我的 7.1 系统上,查询返回 /QOpenSys/QIBM/ProdData/JavaVM/jdk60/32bit/jre以上是关于实现 Java 存储过程 IBM DB2 for i (AS400)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 IBM Data Studio 中查看 DB2 存储过程的解释计划?
使用 IBM DB2 Connect 驱动程序调用 i 系列上的存储过程