Oracle JDBC中的PreparedStatement占位符过多

使用Oracle数据库时,导致ORA-01745(“无效的主机/绑定变量名称错误”)错误的原因有多种。 关于错误ORA-01500到ORA-02098Oracle 9i文档提供了有关ORA-01745的更多详细信息。 它指出,“原因”是“绑定变量或INTO规范中的冒号后跟一个不合适的名称,也许是一个保留字。” 它还指出“操作”是“更改变量名称并重试该操作。” 但是,在相同的Oracle 12g文档中 ,没有描述ORA-01745的“原因”或“措施”,原因可能是与此消息相关联的原因有多种,并且有多种相应的措施。 在本文中,我将重点介绍可能不太明显的原因之一,以及对该原因采取的相应措施。

ORA-01745的一些常见原因(我将不在本文中重点介绍)包括使用Oracle数据库保留名保留字 )作为标识符多余或缺少冒号或逗号 ,或尝试绑定结构名(而不是绑定结构名)。变量)到占位符

除了上面列出的原因以及可能的其他潜在ORA-01745原因之外,另一个可能导致ORA-01745错误的情况是使用了太多? Oracle数据库的JDBC PreparedStatement中的占位符。 我将在这篇文章中证明多少? 导致此ORA-01745的PreparedStatement中的占位符为655362 16 )。

以前曾 写过 一篇关于ORA-01795错误的博客 ,该错误是在Oracle SQL IN条件中尝试包含1000个以上的值时发生的。 有多种方法可以解决此限制,一种替代方法可能是使用多个OR来对超过1000个值进行“ OROR 。 通常,这将通过PreparedStatement?来实现? SQL语句中放置的占位符,用于每个OR值。 这种基于PreparedStatement的替代方法使用? 占位符只有在进行“ OR vales数目小于65536时才起作用。

下面的代码清单演示了如何生成针对Oracle HR模式的SQL查询,以使其易于再现过多的ORA-01745错误? 占位符( 可在GitHub上找到完整的代码清单)。

建立指定数量为?准备好的语句 占位符

/**
 * Constructs a query using '?' for placeholders and using
 * as many of these as specified with the int parameter.
 *
 * @param numberPlaceholders Number of placeholders ('?')
 *    to include in WHERE clause of constructed query.
 * @return SQL Query that has provided number of '?" placeholders.
 */
private String buildQuery(final int numberPlaceholders)
{
   final StringBuilder builder = new StringBuilder();
   builder.append("SELECT region_id FROM countries WHERE ");
   for (int count=0; count < numberPlaceholders-1; count++)
   {
      builder.append("region_id = ? OR ");
   }
   builder.append("region_id = ?");
   return builder.toString();
}

下一个代码清单演示了基于在最后一个代码清单中构造的查询来构建PreparedStatement的过程,并使用与?的数量相匹配的多个连续整数设置其占位符? 占位符。

配置PreparedStatement? 占位符

/**
 * Execute the provided query and populate a PreparedStatement
 * wrapping this query with the number of integers provided
 * as the second method argument.
 * 
 * @param query Query to be executed.
 * @param numberValues Number of placeholders to be set in the
 *    instance of {@code PreparedStatement} used to execute the
 *    provided query.
 */
private void executeQuery(final String query, final int numberValues)
{
   try (final Connection connection = getDatabaseConnection();
        final PreparedStatement statement = connection.prepareStatement(query))
   {
      for (int count = 0; count < numberValues; count++)
      {
         statement.setInt(count+1, count+1);
      }
      final ResultSet rs = statement.executeQuery();
      while (rs.next())
      {
         out.println("Region ID: " + rs.getLong(1));
      }
   }
   catch (SQLException sqlException)
   {
      out.println("ERROR: Unable to execute query - " + sqlException);
   }
}

下一个屏幕快照显示当数量为?时发生的ORA-01745错误? 应用的占位符为65536。

此示例显示最大数量为? 可以在Oracle SQL语句中使用的占位符。 幸运的是,还有其他方法可以实现这种类型的功能,而没有ORA-01475限制为65536 ? 占位符或1000个IN元素限制导致ORA-01795错误

翻译自: https://www.javacodegeeks.com/2017/11/many-preparedstatement-placeholders-oracle-jdbc.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值