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

Oracle error code ORA-00913 - IN CLAUSE limitation with more than 65000 values (Used OR condition for every 1k values)

我的应用程序团队正在尝试使用他们的程序动态构建的 SELECT 查询从 table 中获取 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,而是适用于使用 orandnot 的任意组合的任何复合条件,有或没有括号。而且,重要的是,这似乎没有在任何地方记录,也没有被 Oracle 的任何人承认。

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

解析器将 in 条件扩展为复合的 or 分隔条件。适用于您的限制是我已经提到的限制。

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

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

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

解决方法:创建一个临时 table 来存储您的 85,000 个值。请注意,使用元组(人工的)的想法允许您克服单个 in 列表的 1000 个值限制,但它确实 not 绕过限制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