0

SQL Developer で次の PL/SQL スクリプトを実行しようとしています。ループは null のカウントを返す必要がありますが、なぜか毎回 0 を返します。

DECLARE

--v_count number;
v_count_null number;

BEGIN
execute immediate 'select count(*) from SP_MOSAIX' into v_count;

FOR  i in (select column_name from all_tab_COLUMNS where table_name = 'SP_MOSAIX')
LOOP
select count(*) into v_count_null from SP_MOSAIX  where i.column_name IS NULL ;
dbms_output.put_line(v_count_null);

END LOOP;

END;

したがって、これを実行すると、次の出力が得られます。

0 0 0 0 0 0 0 0 0 0 0 0 0 0

しかし、column_name を代入してクエリを手動で実行すると、結果が得られます。

select count(*) into v_count_null from SP_MOSAIX  where i.column_name IS NULL; 

誰でもこれについて助けることができますか?

4

2 に答える 2

2

ここで、注意が必要なことがいくつかあります。まず、言及したように、COUNT クエリは、決して NULL ではない i.column_name の値を使用して実行されます。

次に、値に関係なく、句の条件に一致するCOUNT(*)の数を返します。特定の列にある値の数を数えたい場合は、その列の値を明示的に指定する必要があります。WHERENULLNOT NULLCOUNT

次の例を参照してください ( SQL Fiddle ):

Oracle 11g R2 スキーマのセットアップ:

CREATE TABLE null_col_vals (
  col_without_nulls INTEGER NOT NULL
, col_with_nulls INTEGER
, col_with_mix INTEGER  
)
/

INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, NULL)
/

INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, 1)
/

INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, NULL)
/

クエリ 1 :

SELECT 
  COUNT(col_without_nulls) col_without_nulls
, COUNT(col_with_nulls) col_with_nulls
, COUNT(col_with_mix) col_with_mix
, COUNT(*) all_rows
FROM null_col_vals

結果

| COL_WITHOUT_NULLS | COL_WITH_NULLS | COL_WITH_MIX | ALL_ROWS |
----------------------------------------------------------------
|                 3 |              0 |            1 |        3 |

ご覧のとおり、常に存在する行数を返しますが、他のものは、指定された列に値が存在するCOUNT(*)かどうかによって結果が異なります。NULL

EXECUTE IMMEDIATEを使用して、列名をクエリの一部に変換する必要があります。このようなものは仕事をするかもしれません:

クエリ 2 :

DECLARE

  l_count INTEGER;

BEGIN

  FOR r_col IN (
    SELECT *
    FROM all_tab_columns atc
    WHERE atc.table_name = 'NULL_COL_VALS'
  )
  LOOP

    dbms_output.put_line(r_col.column_name);

    EXECUTE IMMEDIATE 'SELECT COUNT(' || r_col.column_name || ') FROM null_col_vals' 
    INTO l_count;

    dbms_output.put_line(l_count);

  END LOOP;

END;
于 2012-11-20T22:55:33.310 に答える
1

各列を参照できる動的 SQL を使用する必要があります。

FOR  i in (select column_name from all_tab_COLUMNS where table_name = 'SP_MOSAIX')
LOOP
    execute immediate 'select count(*) from SP_MOSAIX  where '||i.column_name||' IS NULL'
     into v_count_null ;
    dbms_output.put_line(i.column_name||' = '||v_count_null);

END LOOP;
于 2012-11-20T22:56:42.090 に答える