【问题标题】:PreparedStatement Does Not Work For Sybase IQ In JavaPreparedStatement 不适用于 Java 中的 Sybase IQ
【发布时间】:2019-05-28 16:02:01
【问题描述】:

我和我的团队遇到了一个问题。我们正在尝试从 Sybase IQ 数据库中检索一些数据,并使用where 子句过滤并获取特定数据。

SQL 已经过测试并且工作正常,但在使用 Prepared Statement 时会失败。

测试完成

  1. 如果我们运行查询(带或不带 where 子句参数),它工作正常。
  2. 如果我们使用在 Prepared Statement 中硬编码的参数运行查询,它也可以正常工作。
  3. 如果我们以编程方式设置预处理语句的参数,它就不起作用。

以上测试确认 JDBC 连接工作正常。

使用 PreparedStatement、JdbcTemplate 或 NamedParameterJdbcTemplate 时会出现相同的错误,因此我怀疑 PreparedStatement 和 Sybase IQ 之间可能存在问题。

有人可以帮忙调查一下吗?我们已经找到了一种解决方法,但是知道为什么这不起作用会非常有用。

我在同一问题上发现了非常相似的主题 (How do I execute PreparedStatement(select object_id()) in sybase iq?),但没有人在那里提供可接受且正确的答案,因此我决定为此创建一个新问题。

使用的代码是:

Class.forName("com.sybase.jdbc4.jdbc.SybDriver");

PreparedStatement stmt = con.prepareStatement("select * from myView where off = ? and acc = ?");

stmt.setString(1, "260");
stmt.setString(2, "9050V");
ResultSet set = stmt.executeQuery();

错误信息是:

Exception in thread "main" java.sql.SQLException: JZ0SA: Prepared Statement: Input parameter not set, index: 0.
    at com.sybase.jdbc4.jdbc.SybConnection.getAllExceptions(Unknown Source)
    at com.sybase.jdbc4.jdbc.SybStatement.handleSQLE(Unknown Source)
    at com.sybase.jdbc4.jdbc.SybStatement.sendQuery(Unknown Source)
    at com.sybase.jdbc4.jdbc.SybPreparedStatement.sendQuery(Unknown Source)
    at com.sybase.jdbc4.jdbc.SybStatement.executeQuery(Unknown Source)
    at com.sybase.jdbc4.jdbc.SybPreparedStatement.executeQuery(Unknown Source)

使用的 JDBC 驱动程序(Maven 依赖):

<dependency>
            <groupId>com.sybase</groupId>
            <artifactId>jconn4</artifactId>
            <version>7.0</version>
</dependency>

【问题讨论】:

  • 请添加执行语句。
  • 虽然 JDBC 驱动程序应该对参数使用基于 1 的索引(JDBC 规范要求),但您是否尝试过使用基于 0 的索引(因为错误消息也使用基于 0 的索引)?在任何情况下,您都应该使用完整的异常堆栈跟踪更新您的问题,并指定您的 Sybase 驱动程序和 Sybase 服务器的 完整 版本。
  • 您使用哪个 JDBC 驱动程序进行连接?
  • 编辑了问题。是的,我尝试过使用基于 0 的索引 - 抛出了 ArrayOutOfBoundsException,因此必须使用基于 1 的索引。
  • 来自您发布的代码:select * from view where off = ? and acc = ?view 是数据库表吗? offacc的数据类型是什么?

标签: java prepared-statement sap-iq


【解决方案1】:

我在使用 sybase iq 时遇到了同样的问题。 我在preparedStatement.execureQuery()语句之前添加了以下两行代码来解决这个问题。

 preparedStatement.setFetchSize(Integer.MAX_VALUE);
 preparedStatement.setFetchDirection(ResultSet.FETCH_FORWARD);

不确定这样做是否正确,但确实有效。

你可以设置 preparedStatement.setCursorName("SomeCursorName"); 这也解决了这个问题。 但在多线程环境下,您需要设置一个唯一的游标名称。可能正在使用随机数或其他东西,并且不要创建太多游标,将它们限制为将同时执行的并发线程数。

【讨论】:

    【解决方案2】:

    我使用了 jconn4 连接属性 LITERAL_PARAMS=t​​rue,它运行良好。小心,性能应该会受到影响。

    当设置为“true”时,PreparedStatement 接口中的 setXXX 方法设置的任何参数都会在执行时插入到 SQL 语句中。如果设置为“false”,则在 SQL 语句中保留参数标记,并将参数值单独发送到服务器。

    【讨论】:

    • 这也解决了我使用 Sybase SQL Anywhere DB 的问题
    【解决方案3】:

    stmt.setString(1, "260"); stmt.setString(2, "9050V");

    数组索引以0开头不是吗?在您使用的 API 中,它不是基于零的索引吗?

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-08
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    相关资源
    最近更新 更多