如何转义 JDBC 预准备语句中的文字问号 ('?')
2022-09-04 05:21:06
我想创建一个JDBC PreparedStatement,如下所示:
SELECT URL,LOCATE ( '?', URL ) pos FROM Links WHERE pageId=? ORDER BY pos ASC
其中 1 个是文本,第 2 个是参数。我可以用它来代替,但我认为额外的函数调用会减慢SQL的执行速度。有没有办法逃脱第一个??
?
CHAR(63)
'?'
?
编辑:
下面的代码测试 dkatzel 的断言,即字符串中的字符不被视为标记:?
public class Test {
public static void main(String[] args) throws SQLException {
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test");
Statement stmt = conn.createStatement();
stmt.executeUpdate("CREATE TABLE Links(URL VARCHAR(255) PRIMARY KEY,pageId BIGINT)");
stmt.executeUpdate("INSERT INTO Links(URL,pageId) VALUES('http://foo.bar?baz',1)");
stmt.executeUpdate("INSERT INTO Links(URL,pageId) VALUES('http://foo.bar/baz',1)");
stmt.close();
PreparedStatement ps = conn
.prepareStatement("SELECT URL,LOCATE ( '?', URL ) pos FROM Links WHERE pageId=? ORDER BY pos ASC");
ps.setLong(1, 1);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
System.out.println(rs.getString(1) + ":" + rs.getInt(2));
}
rs.close();
ps.close();
conn.close();
}
}
输出:
http://foo.bar/baz:0
http://foo.bar?baz:15
看来dkatzel是正确的。我搜索了JDBC规范,找不到任何提及参数标记如果位于引号内将被忽略的提及,但是我发现的ReadyStatement解析器的少数实现(MySql,c-JDBC,H2)似乎都排除了单引号中的文本作为参数标记。?