0

我在 IN 运算符中将 100 个表名作为字符串传递,但由于操作数过多,我收到了数字溢出错误。有没有办法让我使用除 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(..)

注意:对于变量,我使用的是 PLS_Integer。

4

4 回答 4

1

ORA-01426 的建议操作是“减少操作数”。这并不意味着减少操作数的数量。这意味着您试图将太大的数字放入变量中。所以缩小数字,或扩大变量。

你说:

“对于我使用 PLS_Integer 的变量”

所以,如果你有一个大表,我的意思是超过 2,147,483,647 行,你会得到一个数字溢出。因为PLS_INTEGER32 位数据类型

如果这是您的场景,那么您需要声明数据类型的变量INTEGER(或NUMBER(38,0))。


正如@BobJarvis 指出的那样,PLS_INTEGER 针对硬件算术进行了优化。所以一般的建议是使用它来计算类型操作。但是,您的案例只需要一个变量来保存 SQLcount()操作的输出,所以我认为效率不会有任何差异。

于 2014-04-10T05:42:34.780 回答
0

我相信“IN”子句的限制是 1000 个字符串而不是 100 个字符串。调试:

a.) 尝试在 SQL 中运行隐式游标查询。

b.) 如果工作正常,则在替换列名后立即运行查询。此外,尝试增加 not_null_count 和 null_count 变量的大小。

希望能帮助到你

维沙德

于 2014-04-10T05:10:13.157 回答
0

其他一些可能的解决方案

  1. 使用临时表 - 用表名填充它以过滤加入它。
  2. 创建一个全局数组类型

    create type table_of_varchar2 is table of varchar2(30)

使用填充数组和过滤器table_name member of arr_tables_list

于 2014-04-10T06:24:31.867 回答
0

有没有办法让我使用除 IN 之外的其他东西?

考虑改用游标。

于 2014-04-11T14:28:58.707 回答