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

Stored procedures 如何从ref cursor中返回多行的过程中获取网格视图中的数据,stored-procedures,plsql,sys-refcursor,Stored Procedures,Plsql,Sys Refcursor,我有一个包含过程的包,它返回包含多条记录的SYS\u 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(10

我有一个包含过程的包,它返回包含多条记录的SYS\u 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; 我想从这个ref游标中获取/访问对象数组中可能存在的记录。我应该如何接近它。 到目前为止,我已经完成了以下代码:

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包函数或任何其他方法,以及如何指导

我想从中获取/访问对象数组中可能存在的记录 这是一个参考光标

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

将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;
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;
编辑:

但实际上,在您的示例employee中,我的表名是bind变量 这些表包含的列可能会有所不同。那我怎么办 以前不知道我的表名时声明列名

假设您在调用过程时传递表名。您可以在下面找到动态过程。但您需要再次记住,在执行过程中,您需要根据过程中传递的表名修改匿名块中的类型定义

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_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;
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;

谢谢但实际上,在示例employee中,我的表名是bind变量,这些表包含的列可能会有所不同。所以,当我的表名以前不知道时,我如何声明列名呢?老实说,在数据库设计和编码实践中,在检索记录之前不知道表名和结构,这是一种糟糕的做法。它也可能是不安全的。