データディクショナリビューをクエリしています。 メタデータが表示されます 、データベースに関する情報。このビューALL_TAB_COLUMNSには、すべてのテーブルのすべての列の情報が表示されます(権限があります)。必然的にCOLUMN_NAMEをnullにすることはできないため、クエリは行を返しません。
ここで実行したいのは、すべてのテーブルにクエリを実行し、データが含まれていない列を見つけることです。これには動的SQLが必要です。 ALL_TAB_COLUMNSをクエリする必要があるため、完全にオフベースではありませんでした。
動的SQLのため、これはプログラムによるソリューションであるため、結果はDBMS_OUTPUTで表示されます。
set serveroutput on size unlimited
これが匿名ブロックです。実行に時間がかかる場合があります。ビューの列はTAB_COLUMNSに含まれており、結果セットにそれらを含めたくないため、USER_TABLESへの結合が必要です。
declare
dsp varchar2(32767);
stmt varchar2(32767);
begin
<< tab_loop >>
for trec in ( select t.table_name
from user_tables t )
loop
stmt := 'select ';
dbms_output.put_line('table name = '|| trec.table_name);
<< col_loop >>
for crec in ( select c.column_name
, row_number() over (order by c.column_id) as rn
from user_tab_columns c
where c.table_name = trec.table_name
and c.nullable = 'Y'
order by c.column_id )
loop
if rn > 1 then stmt := concat(stmt, '||'); end if;
stmt := stmt||''''||crec.column_name||'=''||'
||'to_char(count('||crec.column_name||')) ';
end loop col_loop;
stmt := stmt || ' from '||trec.table_name;
execute immediate stmt into dsp;
dbms_output.put_line(dsp);
end loop tab_loop;
end;
サンプル出力:
table name = MY_PROFILER_RUN_EVENTS
TOT_EXECS=0TOT_TIME=0MIN_TIME=0MAX_TIME=0
table name = LOG_TABLE
PKG_NAME=0MODULE_NAME=0CLIENT_ID=0
PL/SQL procedure successfully completed.
SQL>
COUNT=0の列には値がありません。
実際にそのような列を削除するかどうかは別の問題です。あなたはそれらに依存するプログラムを壊すかもしれません。したがって、最初に影響分析が必要です。これが、空の列を自動的に削除するプログラムを作成していない理由です。それは危険な行為だと思います。
データベース構造の変更を検討し、監査することが重要です。したがって、このような演習を行う場合は、上記のプログラムからの出力を変更して、レビュー、編集、およびソース管理下に置くことができるドロップ列ステートメントのスクリプトを生成します。