管道表功能

时间:2015-06-11 07:35:01

标签: oracle plsql

我想了解为什么流水线功能没有返回任何结果 我在这里做错了什么想法。

归功于原作者

CREATE OR REPLACE PACKAGE MANAGE_SPACE AS
--Author Tanmay 
g_tblspce_threshold number := 80;
TYPE tblespaces_record IS RECORD(
       tablespace_name VARCHAR2(30), 
       percentage_used NUMBER
       );
TYPE tblespaces_table IS TABLE OF tblespaces_record;

function list_tblspcs_excd_thresld 
return tblespaces_table PIPELINED ;

END MANAGE_SPACE;

包体

CREATE OR REPLACE PACKAGE BODY MANAGE_SPACE
AS
  --Author Tanmay
  FUNCTION list_tblspcs_excd_thresld
    RETURN tblespaces_table PIPELINED
  AS
    tblspaces            tblespaces_record;
  BEGIN
   for x in (SELECT a.tablespace_name tablespace_name,
      ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) percentage_used
      into tblspaces
    FROM dba_tablespaces a,
      (SELECT tablespace_name,
        SUM (BYTES) BYTES
      FROM dba_free_space
      GROUP BY tablespace_name
      ) b,
      (SELECT COUNT (1) DATAFILES,
        SUM (BYTES) BYTES,
        tablespace_name
      FROM dba_data_files
      GROUP BY tablespace_name
      ) c
    WHERE b.tablespace_name(+) = a.tablespace_name
    AND c.tablespace_name(+)   = a.tablespace_name
    AND ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) > g_tblspce_threshold 
    ORDER BY NVL (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES), 0) DESC)
    loop
        PIPE ROW (tblspaces);
    end loop;
    return;
  END list_tblspcs_excd_thresld;
END MANAGE_SPACE;

执行此包不会返回任何行

SQL> select * from table(MANAGE_SPACE.list_tblspcs_excd_thresld())
  2
SQL> /

TABLESPACE_NAME                PERCENTAGE_USED
------------------------------ ---------------

我做错了什么

1 个答案:

答案 0 :(得分:0)

您需要填充数组。最简单的方法是使用BULK COLLECT语法。然后循环遍历数组并输出行。

这是我修改后的软件包版本。

CREATE OR REPLACE PACKAGE BODY MANAGE_SPACE
AS
  FUNCTION list_tblspcs_excd_thresld
    RETURN tblespaces_table PIPELINED
  AS
    -- collection type not record type
    tblspaces             tblespaces_table;
  BEGIN
   select * 
   -- populate the collection
   bulk collect  into tblspaces
   from
   (SELECT a.tablespace_name tablespace_name,
      ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) percentage_used
    FROM dba_tablespaces a,
      (SELECT tablespace_name,
        SUM (BYTES) BYTES
      FROM dba_free_space
      GROUP BY tablespace_name
      ) b,
      (SELECT COUNT (1) DATAFILES,
        SUM (BYTES) BYTES,
        tablespace_name
      FROM dba_data_files
      GROUP BY tablespace_name
      ) c
    WHERE b.tablespace_name(+) = a.tablespace_name
    AND c.tablespace_name(+)   = a.tablespace_name
    AND ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) > g_tblspce_threshold 
    ORDER BY NVL (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES), 0) DESC);
    -- loop round the collection
    for i in 1..tblspaces.count()
    loop
        PIPE ROW (tblspaces(i));
    end loop;
    return;
  END list_tblspcs_excd_thresld;
END MANAGE_SPACE;

这是输出:

SQL> select * from table(MANAGE_SPACE.list_tblspcs_excd_thresld())
  2  /

TABLESPACE_NAME                PERCENTAGE_USED
------------------------------ ---------------
SYSTEM                                     100
SYSAUX                                      91
APEX_2614203650434107                       90
EXAMPLE                                     87
USERS                                       82

SQL> 

@a_horse_with_no_name对内存消耗提出了一个很好的观点。集合保存在会话的内存空间PGA中。在这种特殊情况下,数据库不太可能有足够的表空间来破坏PGA限制。但是对于可能具有更大结果集的其他查询,存在BULK COLLECT ... LIMIT语法,这允许我们将结果集的可管理块提取到我们的集合中。 Find out more