preparedStatement.addBatch()添加了null参数

问题描述 投票:1回答:1

我正在研究一个旧的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);
}

错误消息是法语,因为我在一家法国公司工作,抱歉。

所以这段代码非常基础,因为它受到了我在这里和网上找到的所有例子的启发,但我有一些模糊的错误,我找不到任何信息。

当我按原样运行时,我得到一个例外

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

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

为了解决这个问题,我使用Eclipse调试器来查看我的preparedStatement的运行时值,我发现addBatch()为我的preparedStatement添加了一组空参数!

以下是运行时值的屏幕截图:左图是在运行addBatch()语句之前,右图是在此语句之后。

Screenshot of runtime values

如您所见,包含我的String参数的数组现在包含第二行,该行仅包含null值。

关于数据的说明:

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

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

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

编辑:

我从参数中删除了table_name,而sql命令现在就像“INSERT INTO”+ table_name +“VALUES(?)”

这导致了不同的错误,但它没有解决问题!

实际上,table_name现在是正确的,但[null]行仍然添加到批处理中。因此,批处理中有空VALUES,抛出“java.sql.BatchUpdateException:ORA-00947:值不够”

我的问题与AlexH标记的问题不重复,请撤回此标记。

java jdbc prepared-statement
1个回答
1
投票

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

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

例如在我的情况下,我试图做这样的事情:

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

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

prepareStatement可以处理的唯一格式如下:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.