Java 准备好的语句-将函数用作where子句的一部分
我正在使用Java编写的语句,该语句从Oracle数据库获取数据。由于某些性能问题,查询使用虚拟列作为索引 查询如下所示:Java 准备好的语句-将函数用作where子句的一部分,java,sql,oracle,prepared-statement,Java,Sql,Oracle,Prepared Statement,我正在使用Java编写的语句,该语句从Oracle数据库获取数据。由于某些性能问题,查询使用虚拟列作为索引 查询如下所示: String status = "processed"; String customerId = 123; String query = "SELECT DISTINCT trans_id FROM trans WHERE status = " + status + " AND FN_GET_CUST_ID(trans.trans_id) = " + customerId;
String status = "processed";
String customerId = 123;
String query = "SELECT DISTINCT trans_id FROM trans WHERE status = " + status + " AND FN_GET_CUST_ID(trans.trans_id) = " + customerId;
Connection conn = getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(query);
ps.execute();
...
} catch (...)
这是行不通的。将函数作为where子句的一部分会导致SQLException。我知道CallableStatement,并且知道我可以先使用它,然后连接结果。但是,此表使用FN_GET_CUST_IDtrans_id作为其索引的一部分。有没有一种方法可以使用带有数据库函数的预处理语句作为查询参数
永远不要将SQL的参数连接到字符串中。总是使用占位符吗?和setXxxcolumn,value
如果在您最喜欢的数据库工具中运行SQL,则会出现相同的错误。问题是Oracle出于某种原因无法使用该功能。你得到了什么错误代码
乍一看,这个查询似乎不正确。假设status是varchar列,则在使用status变量前后缺少撇号
String query = "SELECT DISTINCT trans_id FROM trans
WHERE status = '" + status + "' AND FN_GET_CUST_ID(trans.trans_id) = " + customerId;
编辑:我不是java背景。然而,正如@Aron所说,最好使用占位符,然后使用一些方法设置参数值,以避免出现这种情况。如果客户ID是数字,则保留int而不是String。然后尝试执行以下操作:
String query = "SELECT DISTINCT trans_id FROM trans WHERE status = ? AND FN_GET_CUST_ID(trans.trans_id) = ?";
ps = conn.prepareStatement(query);
ps.setString(1, status);
ps.setInt(2, customerId);
ps.execute();
除了预处理语句的其他好处外,您不必记住字符串引号,这很可能会导致错误和特殊字符的转义。应引用已处理状态。也许这就是导致异常的原因,不是吗?如果WHERE子句中有一个函数应该起作用,那么问题可能就在别处。您可以发布错误代码和消息SQLException.getErrorCode吗?查询在SQL*Plus中是否实际工作?抱歉,我发布的示例没有逐字复制。我试着把它剪下来,去掉很多多余的非必要的东西。缺少引号不是问题所在。正如我在对问题的第一次评论中指出的那样,这是正确的。然而,在Aaron提到的queryas中使用占位符可能更好——否则usinf PreparedStatement没有任何好处。问题是函数没有公共执行特权。2在Aaron的评论中,问题在于Oracle出于某种原因无法使用该功能。是什么让我最终发现了问题,所以给了他信任。