如何在JDBC准备好的语句中转义文字问号('?')
技术问答
426 人阅读
|
0 人回复
|
2023-09-14
|
我想创造一个JDBC PreparedStatement,例如:
" S- r! H# K- ~5 [, kSELECT URL,LOCATE URL ) pos FROM Links WHERE pageId=? ORDER BY pos ASC第一个是文字,第二个是参数。CHAR(63)替换,但我认为额外的函数调用会减慢SQL执行速度。第一个逃脱的方法是什么?
7 d+ c! x1 s5 d编辑:0 j, L4 ~1 z) ^" j& p# v# b
以下代码测试dkatzel断言:字符串中的字符不被视为标记:
( O/ j1 J; t3 |; S# ^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()输出:
3 s5 @7 I* ^+ q, f3 e( qhttp://foo.bar/baz:0http://foo.bar?baz:15看来dkatzel是对的。我搜了一下JDBC4 l% f3 j" |" N1 c& L% ]
Spec,但是没有发现,但是没有发现,但是没有发现,但是没有发现6 k& Y. F) j4 e2 C/ v6 K
如果引号中忽略了参数标记,但我发现了PreparedStatement少数实现分析器(MySql,c-JDBC,H2)单个标记中的文本似乎被排除在外。引号作为参数标记。0 O! d6 v' C& B) O- ]2 Q$ U# ?# E
7 m8 q) f" b- B7 Z: l
解决方案:
" E8 j% o, k5 c( q( w$ } 的含义?在SQL在规范中指定JDBC为此遵循规范SQL规范。
; U* X2 |" T3 [0 x/ w驱动程序不会(也不应该)将文本中的问号解释为参数占位符,因为字符串中的问号只是字符串中的字符。有关更多信息,请参见SQL:2011
# K8 h# Y6 s/ Q; iFoundation(ISO-9075-2:2011)第五章。
7 `$ I5 z* {6 @: i4 m/ J因此,转义是不必要的(也不可能)。 |
|
|
|
|
|