Pergunta

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.

Foi útil?

Solução

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.

Outras dicas

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

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

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

Consider using a cursor instead.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top