回答

收藏

如何在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因此,转义是不必要的(也不可能)。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则