2013-10-01 31 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

相关问题