That is because the query:
SELECT COUNT(*) INTO V_COUNT FROM D_T WHERE I.COLUMN_NAME IS NULL;
is just like:
select count(*) into v_count from d_t where 'some string' is null;
I.COLUMN_NAME was bound into the query, it was the name of column and the name of a column is NEVER null.
Here is the query you might have been trying for:
ops$tkyte%ORA11GR2> select count(*) cnt, count(name) cnt_name, count(age) cnt_age
2 from d_t;
CNT CNT_NAME CNT_AGE
---------- ---------- ----------
7 5 4
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> select cnt-cnt_name null_names, cnt-cnt_age null_ages
2 from (
3 select count(*) cnt, count(name) cnt_name, count(age) cnt_age
4 from d_t
5 );
NULL_NAMES NULL_AGES
---------- ----------
2 3
one of those two. I like the first one myself, you might like the second - that would be up to you. And to make this "generic", you could:
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> create or replace procedure count_nulls( p_tname in varchar2, p_result in out sys_refcursor )
2 as
3 l_query varchar2(32000) := 'select count(*) cnt';
4 begin
5 for x in (select column_name
6 from user_tab_columns
7 where table_name = p_tname
8 and nullable = 'Y'
9 order by column_name )
10 loop
11 l_query := l_query || ', count("' || x.column_name || '") "'|| x.column_name || '"';
12 end loop;
13 l_query := l_query || ' from "' || dbms_assert.simple_sql_name( p_tname ) || '"';
14 open p_result for l_query;
15 end;
16 /
Procedure created.
ops$tkyte%ORA11GR2> show errors
No errors.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> variable c refcursor
ops$tkyte%ORA11GR2> exec count_nulls( 'D_T', :c );
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> print c
CNT AGE NAME
---------- ---------- ----
7 4 5
if you want to make it do the other query - that is pretty simple:
ops$tkyte%ORA11GR2> create or replace procedure count_nulls( p_tname in varchar2, p_result in out sys_refcursor )
2 as
3 l_query varchar2(32000);
4 begin
5 for x in (select column_name
6 from user_tab_columns
7 where table_name = p_tname
8 and nullable = 'Y'
9 order by column_name )
10 loop
11 l_query := l_query || ', count(*)-count("' || x.column_name || '") "'|| x.column_name || '"';
12 end loop;
13 l_query := 'select ' || ltrim(l_query,',') || ' from "' || dbms_assert.simple_sql_name( p_tname ) || '"';
14 open p_result for l_query;
15 end;
16 /
Procedure created.
ops$tkyte%ORA11GR2> show errors
No errors.
ops$tkyte%ORA11GR2>
ops$tkyte%ORA11GR2> variable c refcursor
ops$tkyte%ORA11GR2> exec count_nulls( 'D_T', :c );
PL/SQL procedure successfully completed.
ops$tkyte%ORA11GR2> print c
AGE NAME
---------- ----
3 2