sql - Oracle 错误代码 ORA-00913 - IN CLAUSE 限制超过 65000 个值(每 1k 值使用 OR 条件)

标签 sql oracle ora-00913

我的应用程序团队正在尝试使用他们的程序即时构建的 SELECT 查询从表中获取 85,000 个值。

SELECT * FROM TEST_TABLE
   WHERE (
        ID IN (00001,00002, ..., 01000)
   OR   ID IN (01001,01002, ..., 02000)
   ...
   OR   ID IN (84001,84002, ..., 85000)
   ));

但我收到错误“ORA-00913 值太多”。

如果我将 in 子句减少到仅 65,000 个值,则不会收到此错误。 IN CLAUSE(伴随 OR 子句)的值是否有任何限制

最佳答案

问题与 in 无关列表;这是关于or的数量限制- 分隔复合条件。我相信该限制不适用于 or具体来说,但适用于使用 or 的任意组合的任何复合条件, andnot ,带或不带括号。而且,重要的是,这似乎没有在任何地方记录,也没有得到 Oracle 任何人的承认。

您已经清楚地知道,in 中的项目数量限制为 1000 件。列表 - 你已经解决了这个问题。

解析器扩展 in作为化合物的条件,or - 分隔条件。我已经提到过适用于您的限制。

限制为 65,535 个“原子”条件(与 orandnot 放在一起)。编写示例来证实这一点并不困难。

更好的问题是为什么(当然,还有如何解决它)。

我的怀疑:要评估此类复合条件,编译后的代码必须使用堆栈,而堆栈很可能是作为数组实现的。该数组由无符号 16 位整数索引(为什么这么小,只有 Oracle 知道)。所以堆栈大小不能超过2^16 = 65,536;实际上只少了一个,因为 Oracle 认为数组索引从 1 开始,而不是从 0 开始 - 因此它们会丢失一个索引值 (0)。

解决方法:创建一个临时表来存储 85,000 个值。请注意,使用元组的想法(尽管是人为的)可以让您克服单个 in 的 1000 个值限制。列表,但它不能绕过 or 中 65,535 个“原子”条件的限制。 - 限定复合条件;此限制适用于最一般的情况,无论条件最初来自何处( in 列表或其他任何内容)。

有关 AskTom 的更多信息 - 您可能想从底部开始(我的评论,即线程中的最后一条):

https://asktom.oracle.com/pls/apex/f?p=100:11:10737011707014::::P11_QUESTION_ID:9530196000346534356#9545388800346146842

https://asktom.oracle.com/pls/apex/f?p=100:11:10737011707014::::P11_QUESTION_ID:778625947169#9545394700346458835

关于sql - Oracle 错误代码 ORA-00913 - IN CLAUSE 限制超过 65000 个值(每 1k 值使用 OR 条件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69565172/

相关文章:

java - 尝试将 double 值插入 Oracle 数据库时出现 SQLException

sql - 运行 SQL 查询时出现 "ORA-00913: too many values"错误

MySQL 触发器 - 更新后删除

php - 将 $_SESSION 设置为 MySQL 查询的结果

php - 如何告诉 php 计算数据并从数据库中 +/- 它以获得新数字

sql - 将 MSSQL 'FOR XML PATH' 转换为 Oracle

java - WSJDBCConnection 不包装 Oracle jdbc Connection 类型的对象

mysql - 查询之间的 SQL 复合索引

oracle - 无法执行存储过程