实现Java存储过程IBM DB2 for i(AS400)

时间:2015-04-07 09:08:28

标签: 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) 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目录中。

有关如何解决此问题的任何建议?

2 个答案:

答案 0 :(得分:0)

您可能无法以正确的方式指定过程。查看OS400Java stored proc (see Chap 7)的文档,我认为您在此处缺少几个步骤。我建议从文档中获取代码并运行它,然后替换为您自己的实现。

答案 1 :(得分:0)

您的Java代码存在一些问题。

  1. 您不应在Java存储过程中使用System.out。由于系统的性质,如果在回收的QZDASOINIT或QSQSRVR作业中调用Java存储过程,则System.out无法正常工作。

  2. 您不应在通话中使用System.exit(1)。该调用将结束JVM,一旦JVM结束,就无法重新启动。

  3. 如果要访问定义了Java存储过程的同一系统上的表,则可能应该使用本机JDBC驱动程序。要获取使用本机驱动程序的JDBC连接,应调用DriverManager.getConnection(" jdbc:default:connection");

  4. 如果您没有捕获异常,那么如果使用JDBC客户端调用存储过程,则大多数JDBC异常将正确返回。

  5. 我将程序更新为如下所示。

    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