我有100列,其中一些没有任何值(它们是空的)我如何搜索空列并从表中删除并更新数据库?我试过这个查询,但它不起作用。它显示选择了0行。选择后如何更新数据库?
select table_name, column_name
from all_tab_columns
where table_name='some_table'
and column_name is NULL;
谢谢,
答案 0 :(得分:1)
您正在查询数据字典视图。它显示了关于数据库的元数据。此视图ALL_TAB_COLUMNS显示每个表的每一列的信息(您具有权限)。必然COLUMN_NAME不能为空,因此您的查询不会返回任何行。
现在您要做的是查询每个表并查找哪些列中没有数据。这需要动态SQL。您将需要查询ALL_TAB_COLUMNS,因此您并非完全偏离基础。
由于动态SQL,这是一个程序化解决方案,因此结果将显示在DBMS_OUTPUT中。
set serveroutput on size unlimited
这是一个匿名块:可能需要一些时间才能运行。必须连接到USER_TABLES,因为视图中的列包含在TAB_COLUMNS中,我们不希望结果集中的列。
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的任何列都没有值。
现在,您是否真的想放弃这些列是另一回事。您可能会破坏依赖于它们的程序。因此,您首先需要进行影响分析。这就是为什么我没有生成一个自动删除空列的程序。我认为这将是危险的做法。
考虑和审核对数据库结构的更改至关重要。因此,如果我要进行这样的练习,我会改变上面程序的输出,因此它生成了一个drop column语句脚本,我可以查看,编辑并保持在源代码管理下。