我有一个包含过程的包,它返回包含多个记录的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包函数或任何其他方法以及如何指导。
答案 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;