Java 如何在带变量的PreparedStatement中使用SQL通配符

Java 如何在带变量的PreparedStatement中使用SQL通配符,java,sql,oracle,prepared-statement,Java,Sql,Oracle,Prepared Statement,在我的网站上,我需要使用最终用户提供的值执行通配符查询。最佳实践是使用PreparedStatement,主要是为了避免SQL注入。我的查询非常长,因此这是一个示例: String query = "SELECT ... FROM ... WHERE ..."+ // "AND UPPER(CUST_NAME) LIKE UPPER('%?%')"; PreparedStatement pstmt = conn.prepareStatement(query); stmt.setString(1,

在我的网站上,我需要使用最终用户提供的值执行通配符查询。最佳实践是使用PreparedStatement,主要是为了避免SQL注入。我的查询非常长,因此这是一个示例:

String query = "SELECT ... FROM ... WHERE ..."+ //
"AND UPPER(CUST_NAME) LIKE UPPER('%?%')";
PreparedStatement pstmt = conn.prepareStatement(query);
stmt.setString(1, "joe");
问题是setString()引发异常:SQL异常:无效列索引

String query = "SELECT ... FROM ... WHERE ..."+ //
"AND UPPER(CUST_NAME) LIKE UPPER(?)";
PreparedStatement pstmt = conn.prepareStatement(query);
stmt.setString(1, "%joe%");

您可以使用

like upper('%' || ? || '%')
更具可读性。

替换

UPPER('%?%')
…与

UPPER(?)
…然后将参数值设置为:

pstmt.setString(1, "%joe%");

顺便说一句,此查询可能会导致性能不佳。为了获得良好的性能,您需要在
UPPER(CUST\u NAME)
(在
CUST\u NAME
上使用普通的“索引”是不够的)并且您只需要按前缀进行查询(例如“joe%”)。索引无法加快按后缀(如“%joe”或“%joe%”)进行查询的速度。

找到了答案:将“UPPER”(“%?%”)替换为这个“UPPER”(CONCAT(CONCAT)(“%,?),“%)”)“有人有任何其他或更好的建议吗?
UPPER(CONCAT(“%,?,”)
MS SQL:like UPPER(“%”+?+”)