单个Oracle语句中的OR子句的最大数量是多少?

时间:2013-11-04 21:49:32

标签: sql oracle

假设我必须针对单个更新语句检查100,000个uid - 我的代码目前将其分解为1000个uid块:

[...] WHERE UID IN (..., '998', '999', '1000') 
OR UID IN ('1001', '1002', ...) 
OR (..., etc., ...)

您可以拥有最多OR条款吗?即,在我上面的例子中,它将生成每个1000 IN子句的100个OR子句。

2 个答案:

答案 0 :(得分:2)

<强> 22

嗯,不完全是。这就是1000项IN列表中有多少OR子句将在我的系统上运行,但这个数字可能会因人而异。有 没有database limit完全覆盖这种情况。它可能属于注意:

  

SQL语句可以使用多长时间的限制取决于许多因素,   包括数据库配置,磁盘空间和内存

当我尝试23时,我在SQL * Plus中遇到此错误:

ERROR at line 1:
ORA-03113: end-of-file on communication channel
Process ID: 2452
Session ID: 135 Serial number: 165

这不是真正的错误,只是意味着服务器崩溃,SQL * Plus失去了连接。奇怪的是,当我查看警报日志时,没有错误。有跟踪文件但仍然没有ORA错误消息。我看到的只有数百行:

*** 2013-11-04 21:59:48.667
minact-scn master-status: grec-scn:0x0000.00821c54 gmin-scn:0x0000.0081d656 gcalc-scn:0x0000.00821c54
minact-scn master-status: grec-scn:0x0000.00823b45 gmin-scn:0x0000.0081d656 gcalc-scn:0x0000.00823b46

这里的教训是避免可笑的大型SQL语句。您必须以另一种方式执行此操作,例如将数据加载到表中。并且不要尝试构建 足够小的东西。它可能在今天起作用,但明天会在不同的环境中失败。


--Find the maximum number of IN conditions with 1000 items.
--Change the first number until it throws an error.
--This code uses dynamic SQL, but I found that static SQL has the same limit.
declare
    c_number_of_ors number := 22;

    v_in_sql varchar2(4000);
    v_sql clob;
    v_count number;
begin
    --Comma-separate list of 1000 numbers.
    select listagg(level, ',') within group (order by 1)
    into v_in_sql
    from dual connect by level <= 1000;

    --Start the statement.
    v_sql := 'select count(*) from dual ';
    v_sql := v_sql || 'where 1 in ('||v_in_sql||')';

    --Append more ORs to it.
    for i in 1 .. c_number_of_ors loop
        v_sql := v_sql || ' or '||to_char(i)||' in ('||v_in_sql||')';
    end loop;

    --Execute it.
    execute immediate v_sql into v_count;
end;
/

答案 1 :(得分:1)

单个查询中没有OR子句的任何限制。使用GROUP BY子句时可能存在限制问题,一般而言,所有非均匀聚合函数(例如,SUM,AVG)都必须适合单个数据库块。