Oracle 将动态结果集提取到游标中的最佳方法
我有一个报告函数,它接受SQL查询并在其上生成一些聚合和转换。所有查询都返回具有以下结构的列:ID、COL1、COl2、COL3。。。。COL25 该函数将结果提取到游标中以进行处理,并将行存储在变量中,如下所示:Oracle 将动态结果集提取到游标中的最佳方法,oracle,plsql,Oracle,Plsql,我有一个报告函数,它接受SQL查询并在其上生成一些聚合和转换。所有查询都返回具有以下结构的列:ID、COL1、COl2、COL3。。。。COL25 该函数将结果提取到游标中以进行处理,并将行存储在变量中,如下所示: OPEN C1 FOR V_SQL; LOOP CASE COLUMN_COUNT WHEN 3 THEN FETCH C1 INTO ROW.C1,ROW.C2,
OPEN C1 FOR V_SQL;
LOOP
CASE COLUMN_COUNT
WHEN 3 THEN
FETCH C1 INTO ROW.C1,ROW.C2,ROW.C3;
WHEN 4 THEN
FETCH C1 INTO ROW.C1,ROW.C2,ROW.C3,ROW.C4;
WHEN 5 THEN
FETCH C1 INTO ROW.C1,ROW.C2,ROW.C3,ROW.C4,ROW.C5;
... (until 29 columns)
详情如下:
OPEN C1 FOR V_SQL;
LOOP
CASE COLUMN_COUNT
WHEN 3 THEN
FETCH C1 INTO ROW.C1,ROW.C2,ROW.C3;
WHEN 4 THEN
FETCH C1 INTO ROW.C1,ROW.C2,ROW.C3,ROW.C4;
WHEN 5 THEN
FETCH C1 INTO ROW.C1,ROW.C2,ROW.C3,ROW.C4,ROW.C5;
... (until 29 columns)
现在,我需要支持多达100个列。这将使代码非常大。如何像数组一样以动态方式实现这一点?此过程接收SQL查询文本(来自安全源-请注意,否则您应该对恶意代码执行一些基本检查)以及许多要获取的列 该过程解析查询,动态定义所需计数中的列,并获取行以生成DBMS_输出-您应该了解您的用例 您可以省略
col\u cnt
参数,并使用DBMS\u SQL从游标获取值。描述列
,但这需要额外打开/关闭游标
CREATE OR REPLACE PROCEDURE ftch (
sql_txt IN VARCHAR2,
col_cnt IN NUMBER) IS
type array_vc_t is varray(100) of varchar2(30);
id NUMBER;
cols array_vc_t := array_vc_t();
source_cursor INTEGER;
ignore INTEGER;
BEGIN
source_cursor := dbms_sql.open_cursor;
DBMS_SQL.PARSE(source_cursor,sql_txt, DBMS_SQL.NATIVE);
DBMS_SQL.DEFINE_COLUMN(source_cursor, 1, id);
for i in 1..col_cnt loop
cols.extend();
DBMS_SQL.DEFINE_COLUMN(source_cursor, i+1, cols(i), 30);
end loop;
ignore := DBMS_SQL.EXECUTE(source_cursor);
LOOP
IF DBMS_SQL.FETCH_ROWS(source_cursor)>0 THEN
DBMS_SQL.COLUMN_VALUE(source_cursor, 1, id);
for i in 1..col_cnt loop
DBMS_SQL.COLUMN_VALUE(source_cursor, i+1, cols(i));
end loop;
dbms_output.put_line('id= '|| id );
for i in 1..col_cnt loop
dbms_output.put_line(' i='|| i || ' col = '|| cols(i) );
end loop;
ELSE
-- No more rows - exit
EXIT;
END IF;
END LOOP;
DBMS_SQL.CLOSE_CURSOR(source_cursor);
EXCEPTION
WHEN OTHERS THEN
IF DBMS_SQL.IS_OPEN(source_cursor) THEN
DBMS_SQL.CLOSE_CURSOR(source_cursor);
END IF;
RAISE;
END;
/
范例
exec ftch('select id, col1, col2 from tab',2);
输出
id= 1
i=1 col = xx1
i=2 col = xx2
id= 2
i=1 col = yy1
i=2 col = yy2
id= 3
i=1 col = zz1
i=2 col = zz2
请看一看oracle动态sql包。对于年轻程序员@OldProgrammer来说,这是一个很好的学习任务,感谢您的启发;)