如何在jdbc / DB2连接中插入其他库?

时间:2015-01-08 16:37:50

标签: jdbc db2 ibm-midrange

我正在编写一个小程序,通过jdbc(db2jcc.jar版本1.0.581)在AS / 400 DB2表中写入数据,并且触发器与INSERT操作相关联。此触发器适用于与包含我的表(f4104)的库(jdta73p10)不同的库关联的各种表。

按照我用来建立连接的代码并读取完美运行的数据。

import java.sql.*;
import com.ibm.db2.jcc.*;

public class ProvaNUMEAN13 {

public static void main(String[] args) throws SQLException, ClassNotFoundException {

    DB2DataSource dbds = new DB2DataSource();

    dbds.setDriverType(4);
    dbds.setServerName("a60d45bb");
    dbds.setPortNumber(446);
    dbds.setDatabaseName("prodgrp");
    dbds.setDescription("Prova collegamento");
    dbds.setUser("XXXXX");
    dbds.setPassword("XXXXX");

    Connection con = dbds.getConnection();

    Statement stmtNum = con.createStatement();
    stmtNum.executeQuery("select * from INTERFACCE.NUMEAN13");
    ResultSet rs = stmtNum.getResultSet();

    rs.next();  
    System.out.println("Valore numeratore: " + rs.getString("E13EAN"));
    System.out.println("Tipo numeratore: " + rs.getString("K13KEY"));

    stmtNum.close();

    Statement stmtAnag = con.createStatement();
    stmtAnag.executeQuery("select * from jdta73p10.f4101lb where IMLITM = " + "'" + args[0] + "'");
    ResultSet rsAna = stmtAnag.getResultSet();
    int idCodice = 0;
    if (!rsAna.next()) {

        System.out.println("Il codice " + args[0] + " non esiste in anagrafica!");

    } else {

        idCodice = rsAna.getInt("IMITM");
        System.out.println("idCodice per " + args[0] + ": " + Integer.toString(idCodice));
        Statement stmtQEAN = con.createStatement();
        stmtQEAN.executeQuery("select IVALN, IVCITM, IVLITM, IVDSC1 from jdta73p10.f4104 where IVXRT = 'B ' and IVALN = '8000000000000'");
        ResultSet rsQEAN = stmtQEAN.getResultSet();

        if (rsQEAN.next()) {
            System.out.println("Codice EAN per " + args[0] + " già presente: " + rsQEAN.getString("IVALN"));
            System.out.println("Valore EAN13: " + rsQEAN.getString("IVCITM"));
            System.out.println("Risultato ricerca per EAN13: " + rsQEAN.getString("IVLITM")+" - "+rsQEAN.getString("IVDSC1"));

        }
    }
}
}

问题是当我尝试执行INSERT操作时(如下所示);由于触发器执行,AS / 400中会生成错误。

stmtQEAN.execute("insert into jdta73p10.f4104 (IVXRT,IVITM,IVCITM,IVDSC1,IVALN,IVLITM) values ('B ','18539','8000000000000','Prodotto PROVA','8000000000000','ABABABAB')");

这是AS / 400方面的错误:

  

消息ID。 。 。 。 。 。 :RNQ0211严重性。 。 。 。 。 。 。 :99

     

消息类型。 。 。 。 。 :查询

     

发送日期。 。 。 。 。 。 :08/01/15发送时间。 。 。 。 。 。 :10:01:31

     

消息。 。 。 。 :调用程序或过程时出错   * LIBL / PRHWRAPUSE(C G D F)。   原因。 。 。 。 。 :程序INTERFACCE / TRG_F4104A中的RPG程序TRG_F4104A   语句152尝试调用程序或过程* LIBL / WS_MATERI,但是   无法访问程序或过程,库或必需的   服务计划。如果名称为* N,则调用是按过程进行的绑定调用   指针。

     

恢复。 。 。 :检查作业日志以获取有关原因的更多信息   错误并联系负责程序维护的人员。   回复邮件的可能选择。 。 。 。 。 。 。 。 。 。 。 。 。 。 。 :

     

D - 获取RPG格式的转储。

     

S - 获取系统转储。

我的问题是:如何指定触发需要的其他库?在旧版本的工具(用Delphi编写)中,我使用了Client / Access ODBC,在那里有一个特殊字段,您可以在其中输入其他库但现在我不知道该怎么做。

4 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题。用户配置文件具有作业描述,并且该作业描述具有库列表。我将为您的JDBC连接设置用户配置文件/作业描述组合。

如果这不够动态,请考虑编写一个可以调用的存储过程,它将按照您需要的方式设置库列表。

另一种方式可能太不灵活但我提到它作为替代方案。不要将* LIBL用于服务程序,而是指定库。一方面,这使得在测试和生产中不可能使用相同的程序。另一方面,它使得某人无法在中间插入自己的库。

如果你真的被卡住了并且IBM方面没有人能够为你做出改变,你可以CALL QCMDEXC as a stored procedure从客户端自己改变库列表。这是最不可取的,因为它意味着客户端和服务器之间的紧密耦合。如果IBM团队真诚地设置测试环境(或灾难恢复环境!),则必须更改客户端代码中的所有引用,并将更改分发给使用它的每个人。

答案 1 :(得分:0)

感谢您的提示。

我也在考虑使用存储过程(正如你的建议),但最后我发现使用其他IBM软件包jt400.jar可以使用一个DataSource类,其中包含一个设置AS / 400列表的方法您需要使用的库。

下面我使用 setLibraries 方法修改我的代码(现在可以使用!)。

    import com.ibm.as400.access.*;

    ...

    AS400JDBCDataSource dbds = new AS400JDBCDataSource();

    dbds.setServerName("a60d45bb");
//  dbds.setPortNumber(446);
    dbds.setDatabaseName("prodgrp");
    dbds.setDescription("Prova collegamento a numeratore EAN13");
    dbds.setUser("XXXXX");
    dbds.setPassword("XXXXX");
    dbds.setLibraries("JCOM73P10 JDTA73P10 KLDADBFER KLDADBGAM INTERFACCE SAP");


    Connection con = dbds.getConnection();

这个类没有方法setPort,但如果你使用标准端口(就像我的情况一样)没有问题。如果有必要,我会尝试发现如何设置它。

答案 2 :(得分:0)

AS400(iSeries)允许在jdbc url中使用逗号分隔的库列表:

JDBC:AS400:// someserver;的命名=系统;库= devfiles,prodfiles,SYSIBM等

命名= system 表示sql将使用库列表。例如:

select * from NUMEAN13

naming = sql 表示sql将包含以表引用为前缀的库名。例如:

select * from INTERFACCE.NUMEAN13

我的经验是你无法混合它们。如果使用库列表(命名= system),那么所有sql 都不能包含库名。如果使用非库列表(naming = sql),那么所有sql 必须包含库名。

答案 3 :(得分:0)

夫妻解决方案。

快速实时修复 将触发器程序复制到QGPL(临时修复。永久修复需要尽快实施

更改用于连接AS400的用户配置文件的JOBD,使其具有正确的列表。用于JDBC的用户配置文件应该已被锁定,或者它是组中用户的jdbc,因此这是一个简单的CHGJOBD JOBD(x)LIBL(xxx xxx xxx xxx),但连接必须被回收

更改触发器程序,使其具有硬编码库。我打赌你需要独家访问该文件。我没有工作(无法访问iseries)所以我无法验证此解决方案。

我建议不要更改连接字符串。您最终必须为连接到数据库的每台计算机更改它。