如何从返回ref cursor中多行的过程中获取网格视图中的数据

时间:2017-07-24 07:14:43

标签: stored-procedures plsql sys-refcursor

我有一个包含过程的包,它返回包含多个记录的SYS_REFCURSOR


    PROCEDURE GET_FILTER(VIEWNAME IN VARCHAR2,REPORTID IN INTEGER,FILTERNUMBER IN INTEGER, VIEW_NAME OUT SYS_REFCURSOR)

      IS  
         FILTER_QUERY VARCHAR2(10000 CHAR):=NULL;
         DATAPOINTQUERY VARCHAR2(10000 CHAR):=NULL;
         INTERMEDIATEQUERY VARCHAR2(10000 CHAR):=NULL;
         REPORTFILTERS HCREP_FILTERS%ROWTYPE;
         REPORTTABLEFILTERS NUMBER:=NULL;
         TYPE FILTERARRAY IS VARRAY(5) OF VARCHAR2(100); 
         QUERY_UNION FILTERARRAY;
         FLAGFILTER INTEGER:=0;
         COUNTRECORDS INTEGER:=0;
         STUDY_DATE_CREATED DATE:=NULL;
      BEGIN
          QUERY_UNION := FILTERARRAY(NULL);
          FILTER_QUERY := 'SELECT * FROM ' || VIEWNAME;
          DATAPOINTQUERY := FILTER_QUERY || ' WHERE ';

           FOR REPORTFILTERS IN (SELECT FILTER_TEXT
                                  FROM HCREP_FILTERS
                                  WHERE FILTER_ID =
                                      (SELECT FILTER_ID
                                       FROM
                                         (SELECT FILTER_ID,
                                                 ROW_NUMBER() OVER(
                                                                   ORDER BY ROWID) AS mRow
                                          FROM HCREP_REPORTS_TO_FILTERS
                                          WHERE REPORT_ID =REPORTID)
                                       WHERE mRow =FILTERNUMBER)) LOOP
            QUERY_UNION.EXTEND;
            QUERY_UNION(QUERY_UNION.LAST) := REPORTFILTERS.FILTER_TEXT;
            DATAPOINTQUERY := DATAPOINTQUERY || REPORTFILTERS.FILTER_TEXT;
            FLAGFILTER :=1;
          END LOOP;

          IF FLAGFILTER = 1 THEN 
            FILTER_QUERY := FILTER_QUERY || ' WHERE ';
            FOR indx IN 1 .. QUERY_UNION.count LOOP
              FILTER_QUERY := FILTER_QUERY || QUERY_UNION(indx);
              IF (indx  1 AND QUERY_UNION.count  indx) THEN 
                 FILTER_QUERY := FILTER_QUERY || ' AND ';
              END IF;
            END LOOP;
          END IF;

          OPEN VIEW_NAME FOR FILTER_QUERY;

      END GET_FILTER;

我希望从这个引用游标中获取/访问记录(可能在对象数组中)。我应该如何处理它。 到目前为止,我已经完成了代码:


    SET SERVEROUTPUT ON;
    DECLARE 
      QUERYFILTERS VARCHAR2(1000);
      MAIN_QUERY VARCHAR2(10000);
      v_cursor HC_PACKAGE.SYS_REFCURSOR;
      l_colCnt number;
      l_descTbl dbms_sql.desc_tab;
      v_name_var  VARCHAR2(10000);
      v_num_var   NUMBER;
      v_date_var  DATE;
      v_curid    NUMBER;
      v_row_num    NUMBER;
      p_sql_stmt VARCHAR2(1000);
    BEGIN
      HC_PACKAGE.GET_FILTER('HC_CA_VIVO',2,1,VIEW_NAME => v_cursor);
      v_curid := DBMS_SQL.TO_CURSOR_NUMBER(v_cursor);
      DBMS_SQL.DESCRIBE_COLUMNS( c => v_curid,col_cnt => l_colCnt,desc_t  => l_descTbl );
      FOR i in 1 .. l_colCnt LOOP       
        IF l_descTbl(i).col_type = 2 THEN
            DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_num_var);
        ELSIF l_descTbl(i).col_type = 12 THEN
            DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_date_var);
        ELSE
            DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_name_var, 50);
        END IF;
      END LOOP;
      -- Fetch rows with DBMS_SQL package:
    END;

此代码仅显示消息“ PL / SQL过程已成功完成。”。我应该使用什么DBMS_SQL包函数或任何其他方法以及如何指导。

1 个答案:

答案 0 :(得分:0)

  

我想获取/访问记录(可能是在对象数组中)   这个参考光标。

不清楚你需要什么,但我想你需要做一些事情:

SYS_REFCURSOR作为OUT参数的过程。

CREATE OR REPLACE PROCEDURE sys_refcur_usage ( emp_output    OUT SYS_REFCURSOR)
AS
BEGIN   

   OPEN emp_output FOR 
   select employee_id from employee ;

EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
END;
/

通话:

DECLARE
   a          SYS_REFCURSOR;

   v_emp_id   employee.employee_id%TYPE;
BEGIN
   sys_refcur_usage (emp_output => a);

   LOOP
      FETCH a INTO v_emp_id;

      EXIT WHEN a%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE (v_emp_id);
   END LOOP;
END;

编辑:

  

但实际上我的表名是绑定变量(在你的示例员工中)   这些表包含的列可能会有所不同。那我该怎么办?   在以前不知道我的表名时声明列名。

假设您在调用过程时传递了表名。您可以在下面找到动态过程。但是,您需要记住,在执行时,您需要根据过程中传递的表名修改type中的Anonymous Block定义。

CREATE OR REPLACE PROCEDURE sys_refcur_usage_dyn (
   tab_name         VARCHAR2,
   emp_output   OUT SYS_REFCURSOR)
AS
   TYPE var IS TABLE OF VARCHAR2 (1000)
      INDEX BY PLS_INTEGER;

   colnm      var;

   col_list   VARCHAR2 (4000);

   v_sql      VARCHAR2 (4000);
BEGIN
   SELECT cname
     BULK COLLECT INTO colnm
     FROM col
    WHERE tname = tab_name;

   FOR i IN 1 .. colnm.LAST
   LOOP
      col_list := col_list || colnm (i) || ',';
   END LOOP;

   col_list := RTRIM (col_list, ',');

   v_sql := 'select ' || col_list || '  from   ' || tab_name;

   OPEN emp_output FOR v_sql;

EXCEPTION
   WHEN OTHERS
   THEN
      NULL;
END;
/

通话:

DECLARE
   a          SYS_REFCURSOR;
   v_emp      employee%ROWTYPE; <-- This you need to mention while calling
BEGIN
   sys_refcur_usage_dyn ('EMPLOYEE',emp_output => a);

   LOOP
      FETCH a INTO v_emp;

      EXIT WHEN a%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE (v_emp.employee_id); <-- You can access columns as this way
   END LOOP;
END;