如何用PL/SQL统计表列行数?代码返回全0求错误排查
问题排查与修复
错误原因
你的代码核心问题在于:v_array(i) 是存储列名的字符串,而非表中该列的实际值。原代码中的 case when v_array(i) is null 是在判断列名字符串是否为空,而你已经给数组赋值了有效的列名,所以这个条件永远不成立,最终求和结果始终为0。
修复方案
要正确统计指定列的空值行数(或非空行数),需要使用动态SQL来引用实际列。以下是两种常见需求的修复代码:
1. 统计列的空值行数
set serveroutput on declare type t_list is table of number index by PLS_INTEGER; r_emp t_list; type e_list is varray(4) of varchar(50); v_array e_list; begin v_array := e_list('CLAIRTY_ID','SERV_ACCT_NUMBER','BB_ACQUISITION_TYPE','ONT_ACQ_TYPE'); for i in 1..v_array.count loop -- 动态构建SQL,引用实际列统计空值数量 execute immediate 'select sum(case when ' || v_array(i) || ' is null then 1 else 0 end) from SZ_GOODS_DETAIL' into r_emp(i); dbms_output.put_line(v_array(i) || ' 的空值行数: ' || r_emp(i)); end loop; end; /
2. 统计列的非空行数(更简洁写法)
如果你的需求是统计列中有数据的行数(非空值数量),可以直接用count(column_name),它会自动忽略空值:
set serveroutput on declare type t_list is table of number index by PLS_INTEGER; r_emp t_list; type e_list is varray(4) of varchar(50); v_array e_list; begin v_array := e_list('CLAIRTY_ID','SERV_ACCT_NUMBER','BB_ACQUISITION_TYPE','ONT_ACQ_TYPE'); for i in 1..v_array.count loop execute immediate 'select count(' || v_array(i) || ') from SZ_GOODS_DETAIL' into r_emp(i); dbms_output.put_line(v_array(i) || ' 的非空行数: ' || r_emp(i)); end loop; end; /
额外优化点
- 将
r_emp的类型改为number更合理,因为统计结果是数值类型。 - 使用
v_array.count代替固定的4,避免数组长度变化时需要修改循环条件。
内容的提问来源于stack exchange,提问作者Aman
相关产品推荐
相关产品推荐

