选择计数的 PreparedStatement [重复]
Posted
技术标签:
【中文标题】选择计数的 PreparedStatement [重复]【英文标题】:PreparedStatement for select count [duplicate] 【发布时间】:2015-01-23 02:32:05 【问题描述】:我有一个程序可以计算来自各种数据源的记录数。我将数据库名称和表名称分别存储在名为database_names
和table_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_name
和table_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批量更新
选择查询中的 JDBC PreparedStatement 和参数(?)