100 strings in IN operator, oracle pl/sql

只愿长相守 提交于 2020-01-06 10:42:22

问题


I am passing 100 table_names in the IN operator as strings, but I am getting numeric overflow error due to too many operands. Is there a way where I can use something else besides IN ?

set serveroutput on

 DECLARE
  ...
 BEGIN
   FOR r IN 
   (
     SELECT table_name, column_name
     FROM all_tab_columns 
     WHERE table_name IN (...100 strings)
    )
AND data_type = 'NUMBER'
     ORDER BY table_name, column_id
   )
   LOOP
    execute immediate 'SELECT COUNT("' || r.column_name || '")
                             ,COUNT(nvl2("' || r.column_name || '", NULL, 1))                        
                       FROM "' || r.table_name || '"'
    INTO not_null_count, null_count;

    DBMS_OUTPUT.PUT_LINE(..)

Note: For variables I am using PLS_Integer.


回答1:


The suggested action for ORA-01426 is "reduce the operands". This doesn't mean reduce the number of operands. It means you're trying to put too large a number into a variable. So shrink the number, or enlarge the variable.

You say:

"for variables I am using PLS_Integer"

So, if you have a large table, and by large I mean more than 2,147,483,647 rows, you will get a numeric overflow. Because PLS_INTEGER is a 32-bit data type.

If this is your scenario then you need to declare your variables of data type INTEGER instead (or NUMBER(38,0)).


As @BobJarvis points out, PLS_INTEGER is optimized for hardware arithmetic. So the general advice would be to use it for counting type operations. However, your case simply requires a variable to hold the output of a SQL count() operation, so I don't think there will be any difference in efficiency.




回答2:


I believe the limit on 'IN' clause is 1000 strings and not 100 strings. To debug:

a.) Try running your implicit cursor query in SQL.

b.) If it works fine then run the query in execute immediate after substituting the column name. Also , try increasing the size of your not_null_count and null_count variables.

Hope it Helps

Vishad




回答3:


some other possible solutions

  1. use a temp table - populate it with the table names to filter join to it.
  2. create a global array type

    create type table_of_varchar2 is table of varchar2(30)

populate the array and filter using table_name member of arr_tables_list




回答4:


Is there a way where I can use something else besides IN ?

Consider using a cursor instead.



来源:https://stackoverflow.com/questions/22978970/100-strings-in-in-operator-oracle-pl-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!