0

我有非常大的 Oracle 表,其中有许多与我使用的每个过滤器无关的列。

我想在 Oracle 中编写一个查询或函数,它返回只有空值的列的名称,或者返回不为空的列的名称。

4

2 回答 2

3

如果您只想查找始终为空的列,您可以运行此查询创建的查询,那些值为 0 的列为空。

select 'select ' 
       || listagg('count(' || column_name || ') as ' || column_name, ', ')
           within group (order by column_id)
       || ' from my_table;'
  from user_tab_columns
 where table_name = 'MY_TABLE'

这是一个要演示的SQL Fiddle 。

如果您想要列的名称,则必须使用 PL/SQL。这个函数将返回一个逗号分隔的列名列表,当然你也可以返回一个用户定义的类型等。

create or replace function null_cols( P_TableName varchar2 ) return varchar2 is

   l_cols varchar2(32767);
   l_result number;

begin

   for i in ( select column_name 
                from user_tab_columns
               where table_name = upper(P_TableName)
                     ) loop

      execute immediate 'select count(' || i.column_name || ')
                           from ' || P_TableName
                           into l_result;

      if l_result = 0 then
         l_cols := l_cols || i.column_name || ', ';
      end if;

   end loop;

   return l_cols;

end;
/

这是对同一个SQL Fiddle的扩展,其中添加了该函数。

我必须补充一点,如果您接受用户输入以使用该功能,您应该使用该dbms_assert包来帮助避免 SQL 注入。

于 2012-07-15T09:12:24.177 回答
0

您可以使用以下查询来识别相同的,请确保您收集统计信息以获得正确的结果

    select table_name, column_name
      from user_tab_cols         
                where table_name = 'MY_TABLE'
       and NUM_DISTINCT = 0
       and NUM_NULLS > 0

更新 1: - 如果您定期收集统计数据(不是 100% 统计数据),您可以使用 Ben 的答案并对其进行优化。下面将减少需要检查的列数

for i in ( select column_name 
            from user_tab_columns
           where table_name = upper(P_TableName)
           and num_distinct=0 and num_nulls > 0
                 ) loop
于 2012-07-15T08:53:24.043 回答