Java PreparedStatement:单引号上缺少表达式(ORA-00936)

Java PreparedStatement:单引号上缺少表达式(ORA-00936),java,oracle,jdbc,prepared-statement,ojdbc,Java,Oracle,Jdbc,Prepared Statement,Ojdbc,我正在查询Oracle数据库,如下所示: 尝试连接c=dataSource.getConnection; 准备好的报表p=c.准备好的报表 从表中选择*,其中列\字符串=?{ p、 设置字符串1,输入; try ResultSet r=p.executeQuery{ //句柄结果集 } } 并且从用户处接收输入字符串。此调用适用于正常的输入字符串,如: 你好,世界 特殊:字符0_2 ftlo- 但输入字符串失败,如下所示: 7-8信用证y-S' 注意末尾的破折号、正斜杠和单引号 我认为这与单引号

我正在查询Oracle数据库,如下所示:

尝试连接c=dataSource.getConnection; 准备好的报表p=c.准备好的报表 从表中选择*,其中列\字符串=?{ p、 设置字符串1,输入; try ResultSet r=p.executeQuery{ //句柄结果集 } } 并且从用户处接收输入字符串。此调用适用于正常的输入字符串,如:

你好,世界 特殊:字符0_2 ftlo- 但输入字符串失败,如下所示:

7-8信用证y-S' 注意末尾的破折号、正斜杠和单引号

我认为这与单引号有关,但我的印象是,PreparedStatement为您解决了所有问题。有没有人见过这样的问题,或者更了解oracle JDBC驱动程序中的字符转义

我正在使用:

Java:1.8.0_181 Jboss:EAP 6.4.7.GA JDBC:ojdbc6版本11.2.0.3.0 数据库:Oracle数据库11g企业版11.2.0.4.0版-64位生产 堆栈跟踪:

SQLSyntaxErrorException:ORA-00936:缺少表达式 java:445 java:396 oracle.jdbc.driver.T4C8Oall.processErrorT4C8Oall.java:879 oracle.jdbc.driver.T4CTTIfun.receiveT4CTTIfun.java:450 oracle.jdbc.driver.T4CTTIfun.doRPCT4CTTIfun.java:192 java:531 oracle.jdbc.driver.T4CPreparedStatement.doOall8T4CPreparedStatement.java:207 oracle.jdbc.driver.T4CPreparedStatement.ExecuteForderDescripte4cpreparedStatement.java:884 oracle.jdbc.driver.OracleStatement.ExecuteMayBeDescriptionOracleStatement.java:1167 oracle.jdbc.driver.OracleStatement.doExecuteWithTimeoutOracleStatement.java:1289 oracle.jdbc.driver.OraclePreparedStatement.executeInternalOraclePreparedStatement.java:3584 oracle.jdbc.driver.OraclePreparedStatement.executeQueryOraclePreparedStatement.java:3628 oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQueryOraclePreparedStatementWrapper.java:1493 org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQueryWrappedPreparedStatement.java:462 ...
可能是单引号引起的问题,因为在Oracle中,最后一个必须重复两次才能作为单引号输入,或者整个字符串必须包含在q'{…}'构造中,其中。。。是给定的字符串。

无法复制。从中添加了文件ojdbc6-11.2.0.3.jar

针对12.1.0.2服务器值运行以下代码以获取连接当然已被屏蔽

输出

你好,世界 0行 特殊:字符0_2 ftlo- 0行 7-8信用证y-S' 0行 X X 1行
事实证明,我得到的错误与我想象的不同。在主查询完成后,我的ResultSetHandler正在执行一些额外的清理逻辑,这就是抛出SQLException missing表达式。由于apachedbutils和JDBC库的实现,错误被忽略了,并且没有以有用的方式打印出来。很抱歉给您带来混淆。

通常是1个准备好的语句。setString`会处理好它。至少这是PraveReDestEngTrimeCytoError的一个目的:1方法OpenDebug对于类型数据源2是未定义的。方法PraseRetring,String在PravaReDebug语句中不适用于参数,Strigi不会真的认为这是一个有效的测试,但是,因为SELECT语句似乎为任何非X的字符串返回0行。@JeffBrower查询是否实际返回数据并不重要。问题中的错误是SQL语法错误,这意味着这是解析SQL语句的问题,而不是执行SQL语句的问题。
public static void main(String[] args) throws Exception {
    test("hello world");
    test("special: characters 0_2 (ftlo) -");
    test("7-8 l/o y-S '");
    test("X");
}
private static void test(String input) throws SQLException {
    System.out.println(input);
    try (Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@XXX:1521:XXX", "XXX", "XXX")) {
        String sql = "select DUMMY from DUAL where DUMMY = ?";
        try (PreparedStatement stmt = conn.prepareStatement(sql)) {
            stmt.setString(1, input);
            try (ResultSet rs = stmt.executeQuery()) {
                int count = 0;
                while (rs.next()) {
                    System.out.println("  " + rs.getString("DUMMY"));
                    count++;
                }
                System.out.println("  " + count + " rows");
            }
        }
    }
}