2016-03-03 113 views
0

我寫了一個查詢找到列,而不從動態表中的數據, 但其給出的輸出只能用ROWNUM = 1,這也是不正確的,查詢從表中發現沒有數據的列動態

WITH x AS (SELECT column_name FROM all_tab_cols 
WHERE OWNER='HR' AND table_name='EMPLOYEES' AND ROWNUM=1)  
SELECT X.column_name,count(X.column_name) 
FROM EMPLOYEES,X 
/*CONNECT BY LEVEL <= (SELECT count(1) FROM all_tab_cols 
WHERE OWNER='HR' AND table_name='EMPLOYEES')*/ 
group by X.column_name; 

COLUMN_NAME     COUNT(X.COLUMN_NAME) 
------------------------------ ---------------------- 
EMPLOYEE_ID     20 

當我嘗試使用水平,使其動態失敗,

WITH x AS (SELECT column_name FROM all_tab_cols 
WHERE OWNER='HR' AND table_name='EMPLOYEES' AND ROWNUM=level)  
SELECT X.column_name,count(X.column_name) 
FROM EMPLOYEES,X 
CONNECT BY LEVEL <= (SELECT count(1) FROM all_tab_cols 
WHERE OWNER='HR' AND table_name='EMPLOYEES') 
group by X.column_name; 

Error at Command Line:14 Column:5 Error report: SQL Error: ORA-01788: CONNECT BY clause required in this query block 01788. 00000 - "CONNECT BY clause required in this query block"

CUDü糾正達到同樣的查詢?

回答

0

你的查詢有一些問題:

  • 子查詢中with條款不看到其他子查詢level
  • 你不能使用where rownum = 2,你必須做出別名此列,從選擇它內部查詢,但是這部分不需要在你的情況下,
  • 如果你想檢查所有的列,不需要分層suqbquery。

更正查詢是:

with x as (
    select column_name from all_tab_cols 
    where owner='HR' and table_name='EMPLOYEES') 
select x.column_name, count(x.column_name) as cnt 
    from x, employees group by x.column_name; 

...但它總是顯示在employees所有行的每一列的數量。因此,如果您想查找不填充所有數據的列,則需要動態解決方案。您可以在可變v_sql添加類似...where ||'r.column_name' is null

declare 
    v_sql varchar2(1000); 
    v_num number; 
begin 
    for r in (select column_name from all_tab_cols 
      where owner='HR' and table_name='EMPLOYEES' 
      order by column_id) 
    loop 
    v_sql := 'select count('||r.column_name||') from employees'; 
    execute immediate v_sql into v_num; 
    dbms_output.put_line(rpad(r.column_name,30)||' '||v_num); 
    end loop; 
end; 

實例數據和輸出:

create table employees (id number(3), name varchar2(10), hire_date date); 
insert into employees values (1, 'John', trunc(sysdate)); 
insert into employees values (2, 'Paul', trunc(sysdate)); 
insert into employees values (3, 'Mark', trunc(sysdate)-1); 
insert into employees values (4, 'Anna', null); 

ID        4 
NAME       4 
HIRE_DATE      3