在DB2上使用JDBC更新异常

4
引起异常的代码如下:
    for (int i = 0; i < updateParams.size(); i++) {
        s = con.prepareStatement(sSQL);
        params = (String[][]) updateParams.get(i);
        setParamsPreparedStatement(s, params);
        log.debug("executeUpdates: " + sSQL + "[params:" + Arrays.deepToString(params) + "]");
        Date d = new Date();
        s.execute();
        log.info("STATEMENT EXECUTE TIME IN SECOND=" + (new Double(new Date().getTime() - d.getTime()) / 1000));
        rowcount += s.getUpdateCount();
        s.close();
    }

异常发生的确切行是s.execute。

堆栈跟踪信息如下:

com.ibm.db2.jcc.c.SqlException: The value of a host variable in the EXECUTE or OPEN statement is out of range for its corresponding use.
    at com.ibm.db2.jcc.c.fg.d(fg.java:1340)
    at com.ibm.db2.jcc.b.gb.k(gb.java:351)
    at com.ibm.db2.jcc.b.gb.a(gb.java:60)
    at com.ibm.db2.jcc.b.w.a(w.java:52)
    at com.ibm.db2.jcc.b.wb.c(wb.java:213)
    at com.ibm.db2.jcc.c.gg.ab(gg.java:1779)
    at com.ibm.db2.jcc.c.gg.d(gg.java:2324)
    at com.ibm.db2.jcc.c.gg.d(gg.java:2420)
    at com.ibm.db2.jcc.c.gg.X(gg.java:1332)
    at com.ibm.db2.jcc.c.gg.execute(gg.java:1316)

插入数据的查询语句是:

insert into CMP_RULES_ACTIONS (RULE_ID, ACTION_ID, CAMPAIGN_ID, creation_date, LAST_UPDATE_DATE, expiry_date, activation_date, enabled, priority, GROUP_ID, owner) values (?, ?, ?, sysdate, sysdate, to_date(?,'YYYY/MM/DD HH24:MI'), to_date(?,'YYYY/MM/DD HH24:MI'), 1, ?, ?, ?)

参数如下:

[params:[[freebuy_wv_scomm_bonus_perc_863, 12], [sendgenericbonuslist, 12], [863, 4], [2101/01/31 00:00, 12], [2013/03/21 16:14, 12], [0, 4], [null, 12], [null, 12]]]

在谷歌上搜寻异常信息没有任何结果。我是DB2的新手。有人可以帮我吗?

更新

以下是我如何在preparedstatement中设置参数的示例:

public void setParamsPreparedStatement(PreparedStatement s, String[][] params) throws Exception {
    log.debug("Params are: " + Arrays.deepToString(params));
    for (int i = 0; i < params.length; i++) {
        if (params[i][1].equals(ParamTypes.ORA_TYPE_INTEGER)) {
            if (params[i][0] != null && !params[i][0].trim().equals("")) {
                s.setInt(i + 1, Integer.parseInt(params[i][0]));
            } else {
                s.setNull(i + 1, Types.INTEGER);
            }
        }

 ...
}

解决方案

我试图将一个过长的字符串放入一个长度不够的字段中。现在,该字段已经变长,我的代码成功运行。


在设置PreparedStatement参数时,您是否使用基于1的索引? - Mark Rotteveel
此外,那些日期列是DATE还是TIMESTAMPDATE列没有时间部分,而TIMESTAMP有(因此可能需要使用TO_TIMESTAMP - Mark Rotteveel
@MarkRotteveel 这是因为我尝试插入的值太长了,超过了该字段的最大长度。 - Vitaly Olegovitch
很好了解。你可以将你的解决方案发布为自己问题的答案。 - Mark Rotteveel
1
你在日志记录中使用了字符串拼接,这在不同的日志级别被禁用时有点失去了意义(即仍然执行拼接操作,这可能需要相当多的工作)。我知道的大多数日志实用程序都使用一组可变参数替换变量,你应该研究一下。 - Clockwork-Muse
1个回答

1
问题在于一个字段,即RULE_ID,长度太短(VARCHAR(30)),无法容纳我尝试插入的值(“freebuy_wv_scomm_bonus_perc_863”)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接