当前位置: 首页 > 面试题库 >

如何在JDBC准备好的语句中转义文字问号('?')

单喜
2023-03-14
问题内容

我想创建一个JDBC PreparedStatement,例如:

SELECT URL,LOCATE ( '?', URL ) pos FROM Links WHERE pageId=? ORDER BY pos ASC

其中第一个?是文字,第二个?是参数。我可以CHAR(63)代替,'?'但我认为额外的函数调用会减慢SQL的执行速度。有什么办法可以逃脱第一个?

编辑:

以下代码测试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
Spec
,但没有发现?
参数标记如果在引号内将被忽略,但是我发现的PreparedStatement解析器的少数实现(MySql,c-JDBC,H2)似乎都排除了单个标记内的文本。引用中的引号作为参数标记。


问题答案:

的含义?在SQL规范中指定,而JDBC规范为此遵循SQL规范。

驱动程序不会(也不应该)将文字中的问号解释为参数占位符,因为字符串文字中的问号只是字符串文字中的字符。有关更多信息,请参见SQL:2011
Foundation(ISO-9075-2:2011)的第5章。

因此,转义是没有必要的(也不可能)。



 类似资料:
  • 我正在尝试使用准备好的语句和TABLE_CATALOG和table_schema的参数来选择默认模式'public'中的所有表。当我创建一个准备好的语句时,系统会返回一个错误,这没有任何意义。如果我指定了TABLE_CATALOG而不指定TABLE_SCHEMA,它可以很好地工作。另外,如果指定TABLE_SCHEMA而不指定TABLE_CATALOG,它也可以正常工作。我是不是做错什么了? 线程

  • 我正在寻找一种用Java转义MySQL查询的字符串的方法。 但等一下,在你们中的一些人直接下结论说“事先准备好的声明”之前,我想再解释一下。

  • 我正在使用JDBC执行Oracle语句,如下所示: 我在Java找到了几种称呼上面的声明的方法,主要是: > 使用OraclePreparedStatement: 使用CallableStatement: > 方法#2抛出“SQLException:Not all return parameters registered”,但是,如果我将SQL语句包装为“begin..end;”-那么方法2就很好

  • 我目前正在增强一个使用spring和Hibernate的应用程序。有多个应用程序通过准备好的语句与db(postgres)通信的实例。到目前为止,应用程序通过DBCP与postgres通信。 更改:应用程序现在通过pgbouncer与postgres通信。 即:application->dbcp->pgbouncer->postgres 我知道这不是最理想的解决方案,即:有两个池。但由于当前的体系

  • 问题内容: 我知道准备好的语句的功能,但是我不能在这里使用它。我通过HTTP(而不是通过JDBC)将sql查询发送到外部服务器。如何对SQL查询进行转义字符串?有没有办法通过JDBC做到这一点?还是我应该为此使用自定义类/函数? ps另外,我已经连接到其他数据库,因此可以使用JDBC函数。 问题答案: 这听起来很不安全。如果要通过HTTP发送SQL语句,则可能会受到中间人攻击(以及其他攻击)的危害

  • 我正在为我的sqlite日志数据库使用准备好的语句。 我的线程每50ms运行一次,将日志缓冲区中的内容写入数据库。 目前,我正在对每个线程运行一个新的准备好的语句批处理,并在所有数据线写入后关闭它们。 现在我想知道是否最好将准备好的语句保存在内存中,并仅在线程关闭/中断时关闭它? 我之所以进行这种预优化,是因为我希望这个日志线程对主应用程序性能的干扰尽可能小,我可以想象每50秒分配/解析/验证资源