选择计数的 PreparedStatement [重复]

Posted

技术标签:

【中文标题】选择计数的 PreparedStatement [重复]【英文标题】:PreparedStatement for select count [duplicate] 【发布时间】:2015-01-23 02:32:05 【问题描述】:

我有一个程序可以计算来自各种数据源的记录数。我将数据库名称和表名称分别存储在名为database_namestable_names 的数组列表中。我无法让它运行:

for (int i = 0; i < table_names.size(); i++) 
    String query = "select count(1) from ?.?";
    PreparedStatement stmt = connection.prepareStatement(query);
    stmt.setString(1, database_names.get(i));
    stmt.setString(2, table_names.get(i));
    ResultSet rs = stmt.executeQuery();

我收到 ORA-00903: invalid table name 错误。我设置了打印语句以确保我的database_names.get(i)table_names.get(i) 打印出正确的值。它们是,如果我将数据库名称和表名称硬编码到我的query 字符串中,程序就能够计算记录。

如何正确准备我的查询语句,使其具有以下形式:

select count(1) from database_name.table_name

【问题讨论】:

我认为你做不到。 PreparedStatement Javadoc 说(部分)注意:用于设置 IN 参数值的 setter 方法(setShort、setString 等)必须指定与输入参数的已定义 SQL 类型兼容的类型。例如,如果 IN 参数的 SQL 类型为 INTEGER,则应使用方法 setInt。 不存在 setTableName 方法。 @ElliottFrisch 我的database_nametable_name 都是字符串,我使用的是setString() 方法,所以我的查询不应该解析为select count(1) from sampleDB.sampleTable吗? 不,因为表名不是 SQL 类型 VARCHAR、CHAR 等。关键问题是 SQL 类型。此外,由于表正在更改,查询计划将不可重用。只需使用 Statement 并动态构建查询。 预准备语句的主要用途之一是允许数据库为文本创建执行计划。虽然绑定变量可用于标准值,但它们不能用于要访问的表。这完全违背了目的。 这些字段是否来自用户?如果是这样,是的! 【参考方案1】:

Oracle 说:当您准备包含要在运行时提供的输入数据的 SQL 语句或 PL/SQL 块时,SQL 语句或 PL/SQL 块中的占位符会标记必须提供数据的位置。

模式和表名不是数据,而是数据结构。在准备阶段,Oracle 解析语句,检查权限。优化计划。如果没有模式和表名,这是不可能的。 当您的语句准备好时,Oracle 在执行阶段使用绑定变量。

在您的情况下,您必须为每个表创建新的 PreparedStatement

【讨论】:

以上是关于选择计数的 PreparedStatement [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Statement和PreparedStatement批量更新

PreparedStatement 选择执行失败

选择查询中的 JDBC PreparedStatement 和参数(?)

JDBC深入理解Statement和PreparedStatement

PreparedStatement和Statement

在preparedStatement中使用可变数量的参数