oracle动态游标问题: 游标查询的内容是 动态生成的,然后里面具体有多少个字段没办法事先知道,而动态游标赋值一定要用fetch到一个变量,有没办法把动态游标内容赋值到一个记录集或者表中,而这个表的字段和记录集字段是没办法预先定义好的,而是通过系统动态生成的!
具体例子如下:
declare
-- Local variables here
v_sql VARCHAR2(1024);
cur SYS_REFCURSOR;
v_column VARCHAR2(1024);
v_exe VARCHAR2(1024);
begin
---v_sql 是通过一连串的复杂逻辑程序生成的动态内容的 在这里就简单写了
v_sql:='select C_001,b_002,d_003 ..../*具体有多少个字段没办法事先知道*/from table1,table2 .../*具体有多少个字段没办法事先知道*/tablen where 1=1 and /*复杂条件*/';
v_column:= 'C_001+b_002/d_003';--这个变量也是通过复杂的逻辑生成的 没办法事先知道的 但是这里的字段都在 v_sql 中有
--在这里 在 字段前面加上表模式 (用正则表达式怎么写 regexp_replace)
--v_column := replace(replace(REPLACE(v_column,'b_','c.b_'),'c_','c.c_'),,'c_','c.d_');
v_column := regexp_replace(v_column,'(c_|d_|b_)','c.\1');
V_CASE_WHEN:=regexp_replace(upper(V_CASE_WHEN),'(MT_|T_|M_|B_|R_)', 'CUR_LOOP.\1');
OPEN cur FOR v_sql;
LOOP
FETCH cur BULK COLLECT INTO e_table ;--但是这边表/记录集 里面的字段没办法定义 因为没办法事先知道表的结构 有没 什么办法(定义 e_talbe )
FOR i IN 1..e_table(i);
v_exe:='INSERT INTO table_a SELECT'|| v_column||' FROM dual' ; /*这里的动态生成的*/
EXECUTE IMMEDIATE v_exe;
COMMIT;
END LOOP;
end;
具体例子如下:
declare
-- Local variables here
v_sql VARCHAR2(1024);
cur SYS_REFCURSOR;
v_column VARCHAR2(1024);
v_exe VARCHAR2(1024);
begin
---v_sql 是通过一连串的复杂逻辑程序生成的动态内容的 在这里就简单写了
v_sql:='select C_001,b_002,d_003 ..../*具体有多少个字段没办法事先知道*/from table1,table2 .../*具体有多少个字段没办法事先知道*/tablen where 1=1 and /*复杂条件*/';
v_column:= 'C_001+b_002/d_003';--这个变量也是通过复杂的逻辑生成的 没办法事先知道的 但是这里的字段都在 v_sql 中有
--在这里 在 字段前面加上表模式 (用正则表达式怎么写 regexp_replace)
--v_column := replace(replace(REPLACE(v_column,'b_','c.b_'),'c_','c.c_'),,'c_','c.d_');
v_column := regexp_replace(v_column,'(c_|d_|b_)','c.\1');
V_CASE_WHEN:=regexp_replace(upper(V_CASE_WHEN),'(MT_|T_|M_|B_|R_)', 'CUR_LOOP.\1');
OPEN cur FOR v_sql;
LOOP
FETCH cur BULK COLLECT INTO e_table ;--但是这边表/记录集 里面的字段没办法定义 因为没办法事先知道表的结构 有没 什么办法(定义 e_talbe )
FOR i IN 1..e_table(i);
v_exe:='INSERT INTO table_a SELECT'|| v_column||' FROM dual' ; /*这里的动态生成的*/
EXECUTE IMMEDIATE v_exe;
COMMIT;
END LOOP;
end;
11R2PLSQL Packages and Types Reference_e10577.pdf (DBMS_SQL 133-87)
TO_CURSOR_NUMBER Function
CREATE OR REPLACE PROCEDURE DO_QUERY(sql_stmt VARCHAR2) IS
TYPE CurType IS REF CURSOR;
src_cur CurType;
curid NUMBER;
desctab DBMS_SQL.DESC_TAB;
colcnt NUMBER;
namevar VARCHAR2(50);
numvar NUMBER;
datevar DATE;
empno NUMBER := 100;
BEGIN
-- sql_stmt := 'select ...... from employees where employee_id = :b1';
OPEN src_cur FOR sql_stmt USING empno;
-- Switch from native dynamic SQL to DBMS_SQL
curid := DBMS_SQL.TO_CURSORID(src_cur);
DBMS_SQL.DESCRIBE_COLUMNS(curid, colcnt, desctab);
-- Define columns
FOR i IN 1 .. colcnt LOOP
IF desctab(i).col_type = 2 THEN
DBMS_SQL.DEFINE_COLUMN(curid, i, numvar);
ELSIF desctab(i).col_type = 12 THEN
DBMS_SQL.DEFINE_COLUMN(curid, i, datevar);
.......
ELSE
DBMS_SQL.DEFINE_COLUMN(curid, i, namevar);
END IF;
END LOOP;
-- Fetch Rows
WHILE DBMS_SQL.FETCH_ROWS(curid) > 0 LOOP
FOR i IN 1 .. colcnt LOOP
IF (desctab(i).col_type = 1) THEN
DBMS_SQL.COLUMN_VALUE(curid, i, namevar);
ELSIF (desctab(i).col_type = 2) THEN
DBMS_SQL.COLUMN_VALUE(curid, i, numvar);
ELSIF (desctab(i).col_type = 12) THEN
DBMS_SQL.COLUMN_VALUE(curid, i, datevar);
....
END IF;
END LOOP;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(curid);
END;
/