【问题标题】:Prepared Statements IN Clause Java Microsoft JDBC准备好的语句 IN 子句 Java Microsoft JDBC
【发布时间】:2015-12-15 21:39:55
【问题描述】:

我在这里和其他地方看到过这样的例子。
在 IN CLAUSE 中使用 '1' 参数我成功了:

SELECT AVG( ( High_Temperature + Low_Temperature ) / 2.0 ) 
  FROM obs_masterAll 
  WHERE Observation_Valid_Time = ? AND 
        Location_ID IN ( ? );

Microsoft JDBC Driver 4.2 for SQL Server  4.2.6420.100
Parameter Count = 2
2010, 36.5

但是,在 IN CLAUSE 中有多个参数,我明白了:

SELECT AVG( ( High_Temperature + Low_Temperature ) / 2.0 ) 
  FROM obs_masterAll 
  WHERE Observation_Valid_Time = ? 
  AND Location_ID IN ( ?, ? );      <--- PROBLEM HERE

Microsoft JDBC Driver 4.2 for SQL Server  4.2.6420.100
Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near ','.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:191)
    at com.microsoft.sqlserver.jdbc.SQLServerParameterMetaData.<init>(SQLServerParameterMetaData.java:423)
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.getParameterMetaData(SQLServerPreparedStatement.java:1659)
    at CreateAMultiStationDailyLoadCtrAvgHistogram.main(CreateAMultiStationDailyLoadCtrAvgHistogram.java:68)
Java Result: 1

这是我的代码:

  prepStmt = buildPreparedStatement( conn.getConnectionObject() );  //function below
  conn.printDriverInfo();
  sqlDate = new java.sql.Date( beginDate.getTimeInMillis() );
  ParameterMetaData pmData = prepStmt.getParameterMetaData();
  System.out.println( "Parameter Count = " + pmData.getParameterCount() );
  prepStmt.setDate( 1, sqlDate );

  for( i = 0; i < locID.size(); i++ )
  {
    prepStmt.setString( ( i + 2 ), locID.get(i) );
  }

  rslt = prepStmt.executeQuery();

  private PreparedStatement buildPreparedStatement(java.sql.Connection con)
  throws SQLException
  {
    int i;
    StringBuilder sb = new StringBuilder();
    sb.append("SELECT AVG( ( High_Temperature + Low_Temperature ) / 2.0 ) ");
    sb.append("FROM obs_masterAll ");
    sb.append("WHERE Observation_Valid_Time = ? AND " );
    sb.append("Location_ID IN ( " );

    for( i = 0; i < ( locID.size() - 1 ); i++ )
    {
      sb.append( "?" ).append(", ");
    }

    sb.append( "?" ).append(" );");
    System.out.println( sb.toString() );
    return( con.prepareStatement( sb.toString() ) );
  }

问题是我的代码还是 JDBC 驱动程序?

【问题讨论】:

  • 您没有正确地将值分配给占位符。你在 forst for 循环中写了 i
  • “客人” --> 非常感谢您的快速回复!我相信问题出在 SQL 语法上(根据上面堆栈跟踪的第一行)。代码在创建 ParameterMetaData 对象时出错,甚至没有分配参数。

标签: jdbc prepared-statement


【解决方案1】:

我会说这是您使用的 JDBC 驱动程序版本的问题。

我可以使用与您相同版本的 SQL Server JDBC 驱动程序来重现此问题。我无法对 MySQL 或 Oracle 运行相同的查询来重现此问题。我必须从查询末尾删除分号才能让它在 Oracle 上运行,但同样的更改并不能解决 SQL Server 的问题。

如果我改用 community technology preview edition of version 6.0 of the Microsoft JDBC driver(版本 6.0.6629.101),我也无法重现该问题。

【讨论】:

  • 卢克 ---> 你太棒了!特别是对于超越并在 MySql 和 Oracle 上进行测试。我认为这是驱动程序问题,但认为在得出结论之前进行代码审查是合适的。我一定会尝试预览版 6.0 并报告!
  • @user3225536:谢谢!我已经安装了 MySQL 和 Oracle 数据库,所以检查它们不需要太多额外的努力。您问题中的代码对ParameterMetaData 没有太大作用,因此您可以通过不获取参数元数据来避免错误。然而,我怀疑上面的代码取自需要使用ParameterMetaData 的真实代码。这是正确的吗?
  • Luke ---> ParameterMetaData 仅用于调试。这最初是在尝试“设置”参数时出现的。它抱怨说不够。我把它扔在那里看看有多少。故事的其余部分已在上面讲述。再次,我非常感谢你看看这个。第二双眼睛和代码审查总是一件好事。非常感谢!
【解决方案2】:

上面关于 JDBC 驱动程序的响应让我很接近。我使用的是一个非常旧的 Microsoft JDBC 驱动程序,所以升级肯定有帮助。我现在正在使用 Microsoft JDBC 驱动程序 6.0 版(6.0.6629.101 版)的社区技术预览版,而不是按照上面的建议。

但是,我还是遇到了问题。

当我从代码中删除以下行时:

ParameterMetaData pmData = prepStmt.getParameterMetaData();
System.out.println( "Parameter Count = " + pmData.getParameterCount() );

一切都按预期进行!

我不确定为什么“ParameterMetaData”数据类型不起作用,但是从代码中删除后,它确实解决了我的问题。

已修复!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 2013-12-06
    • 2023-02-16
    • 2015-03-16
    相关资源
    最近更新 更多