实现Java存储过程IBMDB2fori(AS400)

实现Java存储过程IBMDB2fori(AS400),java,ibm-midrange,java-stored-procedures,iseries-navigator,Java,Ibm Midrange,Java Stored Procedures,Iseries Navigator,我创建了如下Java存储过程,能够使用AS400 Qshell命令解释器生成.class文件 import java.sql.*; public class sample { public sample(){ super(); } /** * @param args */ public static void Test(int test) th

我创建了如下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
目录中


关于如何解决这个问题有什么建议吗?

您可能没有以正确的方式指定该过程。查看的文档,我认为您在这里遗漏了几个步骤。我建议从文档中获取代码并运行它,然后替换为您自己的实现。

您的Java代码有一些问题

  • 您不应该在Java存储过程中使用System.out。由于系统的性质,如果在回收的QZDASOINIT或QSRVR作业中调用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();                
    }       
    
    }

    当我调用它时,我得到以下异常(因为我没有在我的系统上创建该文件)

    您还需要检查数据库服务器作业的作业CCSID是否不是65535。如果作业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
    

    在哪里调用存储过程?在代码中看不到它。此外,提供完整的堆栈跟踪将help@Ortis,更新了堆栈跟踪。@AntoKris类应该实现
    COM.ibm.db2.app.StoredProc
    接口,对吗?您是否可以尝试一下,看看发生了什么,比如编码问题,您是如何创建存储过程的?你能尝试用iSeries access重新创建它吗?谢谢你的回复。我尝试了您建议的方法,但得到的错误为SQL状态:42724供应商代码:-4304消息:[SQL4304]Java存储过程或用户定义函数SPSSAMPLE,特定名称SPSSample无法加载Java类ÄÄÀÀÀÀÄ/øÊÎÁÊ,原因代码为3。@AntoKris您使用的是哪种IBM i版本?是否可以删除该过程并改用此create语句?创建过程IPTSFILI.SPSAMPLE(在测试整数中)语言JAVA参数样式JAVA DETERMINISTIC修改在空输入外部名称“sample.TEST”版本7.1上调用的SQL数据。感谢您的回复。收到错误消息:[SQL4304]JAVA存储过程或用户定义函数MYJAVASTOREPROC,特定名称MYJAVASTOREPROC无法加载Java类SP,原因代码为1。1--在类路径上找不到该类。请执行以下操作:---在我的7.1系统上,创建函数getProperty(键varchar(200))返回varchar(1024)语言java参数样式java外部名称“java.lang.System.getProperty”---然后从sysibm.sysdummy1--选择getProperty(“java.home”),查询返回/QOpenSys/QIBM/ProdData/JavaVM/jdk60/32bit/jreI遵循了第7章中提到的步骤,但仍然遇到了与“[SQL4304]Java存储过程或用户定义函数SPSAMPLE,特定名称SPSAMPLE无法加载Java类ÄÀÀÀÄ/øÊÎÁÊ(原因代码3)”相同的问题。”你能建议一下解决这个问题的方法吗?你试过运行这个例子吗?如果可行,您可以排除编码问题。我尝试了相同的教程,但错过了java程序“CRTJVAPGM CLSF(db2cusicity.class)OPTIMIZE(40)”的优化。有必要吗?
     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