代码之家  ›  专栏  ›  技术社区  ›  Heratom

准备好的报表。addBatch()添加空参数

  •  1
  • Heratom  · 技术社区  · 7 年前

    我正在开发一个旧的struts应用程序,我需要通过java批处理将数据保存在数据库中(因为我们可能一次添加数千行)。

    因此,我使用这种代码:

    Connection c = null;
    PreparedStatement batch = null, truncate=null;
    String sql = "INSERT INTO ? VALUES (?)";
    try {
        c = getConnection();
        c.setAutoCommit(false);
        batch = c.prepareStatement(sql);
        for (ClassContainingData bean : values) {
            batch.setString(1, bean.getTableName());
            batch.setString(2, bean.getAllFieldsValues());
            batch.addBatch();
        }
        int[] resultats = batch.executeBatch();
        for(int res : resultats) {
            if(res == PreparedStatement.EXECUTE_FAILED) {
                batch.close();
                c.close();
                throw new SQLException("L'ajout des valeurs en base de données a échoué pour au moins une valeur.");
            }
        }
        c.commit();
    } 
    catch (BatchUpdateException b) {
        throw new ServiceException("Erreur lors de l'exécution du batch", b);
    } 
    catch (SQLException s) {
        throw new ServiceException("Impossible de sauvegarder les beans en base.", s);
    } 
    finally {
        getManager().close(batch);
        freeConnection(c);
    }
    

    错误信息是法语的,因为我在一家法国公司工作,对此表示抱歉。

    因此,这段代码非常基础,因为它的灵感来自我在这里和web上找到的所有示例,但我有一些模糊的bug,我找不到相关信息。

    当我按原样运行时,会出现异常

    CAUSE : java.sql.BatchUpdateException: ORA-00903: invalid table name. 
    

    这指出了我的数据中的一个错误,所以我仔细检查了一遍,但我的输入似乎没有问题。

    为了解决这个问题,我使用Eclipse调试器查看 preparedStatement ,我发现 addBatch() 将一组空参数添加到我的 编制的报表 !

    以下是运行时值的屏幕截图:左图是在运行 addBatch() 声明,右图就在该声明的后面。

    Screenshot of runtime values

    如您所见,包含我的字符串参数的数组现在包含第二行,该行仅包含 null 价值观

    数据说明:

    • 这是for循环的第一次迭代,因此它应该只包含一行
    • SQL语句有两个参数:表名,如 TABLE_NAME ,以及要插入的值的格式化列表,如 'Here', 'are', 'values' .

    我也有同样的问题,无论我使用1行输入还是15行输入(是的,我谈到了数千行,但我目前处于测试阶段),如果这可能相关的话。

    你知道这里出了什么问题吗?我不认为我滥用了 addBatch() 声明,我认为我是在向它传递不适当的数据。

    编辑:

    我从参数中提取了table\u名称,sql命令现在如下 “插入到”+table\u name+“值(?)”

    这导致了另一个错误,但并没有解决问题!

    实际上,table\u名称现在是正确的,但仍将[null]行添加到批处理中。因此,批处理中存在空值,这会引发 “java.sql.BatchUpdateException:ORA-00947:值不足”

    我的问题不是亚历克斯标记的问题的重复,请撤回此标记。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Heratom    7 年前

    这个问题与我在同一个程序中遇到的另一个问题有关。 讨论和解决方案是 here .

    作为总结,我们应该知道preparedStatement不能将表的名称用作参数,也不能在参数中放置多个值。

    例如,在我的案例中,我尝试这样做:

    String sql = "INSERT INTO (?) VALUES (?)"
    preparedStatement ps = connection.prepareStatement(sql);
    ps.setString(1, "myTableName");
    ps.setString(2, "'Value1', 'Value2', 3");
    

    如您所见,我希望将3个参数作为一个参数传递,而不区分字符串和整数(以及日期)。

    preparedStatement只能处理以下格式:

    String sql = "INSERT INTO " + tableName + " VALUES (?, ?, ?)";
    

    如果在运行前不知道参数的数量,则必须在运行时构建查询。上面的链接中给出了一个示例。