Stored procedures 如何从ref cursor中返回多行的过程中获取网格视图中的数据
我有一个包含过程的包,它返回包含多条记录的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参数的过程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
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变量,这些表包含的列可能会有所不同。所以,当我的表名以前不知道时,我如何声明列名呢?老实说,在数据库设计和编码实践中,在检索记录之前不知道表名和结构,这是一种糟糕的做法。它也可能是不安全的。