2013-10-01 34 views
4

我需要查詢幫助。該查詢返回數據庫中所有視圖的一列。我的最終目標是讓整個結果集成爲一列,其中包含數據庫中的所有視圖,另一列包含每個對應表中有多少記錄/行。Oracle - 對結果集的每一行執行操作

此:

SELECT DISTINCT OWNER, 
     OBJECT_NAME 
FROM DBA_OBJECTS 
WHERE OBJECT_TYPE = 'VIEW' 
    AND OWNER = 'ADMIN' 

返回的第一列,但是我似乎無法找到一種方法,其聯合:

select count(*) from view_X 

得到結果集的第二列。

任何幫助,將不勝感激。 謝謝

+0

你想知道一個視圖將有多少行返回或有多少行,在每個(或全部)基表? '每個對應表中有多少記錄/行'。不對應''從view_X'選擇計數(*)「。 –

回答

3

隨着一些XML魔術,這可以用一個單一的語句來完成:

select object_name as view_name, 
     to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) c from "'||owner||'"."'||object_name||'"')),'/ROWSET/ROW/C')) as row_count 
from dba_objects 
where object_type = 'VIEW' 
    and owner = 'ADMIN' 
order by 1; 
+0

這真是太棒了!謝謝你們的迴應。但是,這是針對SSRS 2008中的報告,並且當我將代碼插入查詢設計器時,它會給我一個「無效字符」錯誤。很確定它來自「to_number ...」行,但不知道在哪裏和爲什麼。有任何想法嗎? – user1964821

+0

@ user1964821:不知道,從未使用過這個SSRS工具。 –

0

取自Oracle的cursors。他們讓你循環結果集。在您的列表每個視圖

EXECUTE IMMEDIATE 'select ''' || OBJECT_NAME || ''' count(*) FROM ' || OBJECT_NAME' 

:一旦你這樣做,你可以動態執行形式的SQL。

+0

我不認爲這是有效的Oracle語法。 – RBarryYoung

+0

@RBarryYoung不是自己的。我將它更改爲EXECUTE IMMEDIATE,但一般的要點是顯示如何使用視圖名稱形成一個字符串。他將不得不使用遊標並循環遍歷每個視圖的這條語句,但這是每次他應該執行的一般要點。 – Vulcronos

+0

它仍然是無效的Oracle語法,不管任何前面的代碼,這行會引發語法錯誤。 – RBarryYoung

2

這是一個棘手的問題。你無法加入到select count(*) from view_X或類似的東西,使用直接的SQL,所以我能想到的最好的事情是一個函數,它接受一個視圖名稱並返回其數:

CREATE OR REPLACE FUNCTION ViewRowCount(viewName VARCHAR2) RETURN NUMBER 
AS 
    rowCount NUMBER := 0; 
BEGIN 
    EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || viewName INTO rowCount; 
    RETURN rowCount; 
END; 
/

一旦該功能到位BTW

SELECT DISTINCT OWNER, 
     OBJECT_NAME, 
     ViewRowCount(OBJECT_NAME) 
FROM DBA_OBJECTS 
WHERE OBJECT_TYPE = 'VIEW' 
    AND OWNER = 'ADMIN'; 

,我不認爲你需要的DISTINCT此查詢,但我不會有今天DBA訪問這樣做,我不能肯定的:你可以從你的查詢調用它。記錄計數將會很慢,因此如果在使用DISTINCT進行過濾之前存在重複記錄,則每個重複記錄行都會有一個計數,從而使計數更慢。


另外看看Rachcha的解決方案,它不需要像我一樣創建一個新的對象(函數)。如果您要從前端調用,則需要使用類似於我的答案的東西,但如果您要從SQL * Plus調用,Rachcha的工作將會非常順利。

2

埃德吉布斯提供了一個全面的答案。 我有以下解決方案,您正在尋找什麼。

SET serveroutput ON; 
DECLARE 
    x INTEGER; 
BEGIN 
    FOR i IN (SELECT 'ADMIN' AS owner, object_name 
       FROM all_objects 
       WHERE object_type = 'VIEW' 
       AND owner = 'ADMIN') LOOP 
     EXECUTE IMMEDIATE ('SELECT count(*) FROM ' || i.object_name) INTO x; 
     dbms_output.put_line (i.owner || ' | ' || i.object_name || ' | ' || x); 
    END LOOP; 
END; 
/
+0

+1 Rachcha - 非常好。我喜歡你不需要用你的解決方案創建一個新對象。 –

+0

@Ed Gibbs,謝謝!如果我遇到了這個問題,我會改爲實施您的解決方案,特別是當我必須生成報告時。 – Rachcha

相關問題