建议使用动态sql语句,参考: DECLARE cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR; fdbk PLS_INTEGER; BEGIN DBMS_SQL.PARSE (cur, 'SELECT * FROM emp WHERE deptno = 10 order by asc', DBMS_SQL.NATIVE); fdbk := DBMS_SQL.EXECUTE_CURSOR (cur); FOR Nfetch IN 1 .. 5 LOOP
fdbk := DBMS_SQL.FETCH_ROWS (cur); END LOOP; DBMS_SQL.CLOSE_CURSOR (cur);DBMS_SQL.PARSE (cur, 'SELECT * FROM emp WHERE deptno = 10 order by desc', DBMS_SQL.NATIVE); fdbk := DBMS_SQL.EXECUTE_CURSOR (cur); FOR Nfetch IN 1 .. 5 LOOP
fdbk := DBMS_SQL.FETCH_ROWS (cur); END LOOP; DBMS_SQL.CLOSE_CURSOR (cur); END;
定义一个ref游标 变换语句就行了 open ref for 'select * from dual order by 字段 asc'open ref for 'select * from dual order by 字段 desc'
也可以将结果存放到一个plsql表中,就可以自由地从前向后或由后往前读取了
对于这类经常来回循环的数据,我想数据量应该不算太大,我比较推荐一种方式(不是游标,使用BULK COLLECT INTO将数据装入内存数组,在很多情况下循环效率还会优于游标,因为这是一次将需要循环的数据装入内存),不过不知道你是否想用而已,呵呵,参考哈(当然仅仅针对数据量不算太大,如几千以内吧)。 我这里假如你有一个表是(没有的话,用这个做下测试也行,呵呵): CREATE TABLE AAA(A1 NUMBER,A2 VARCHAR2(20)); 数据你可以手写几条进去就OK了,关键是循环了。此时遍历数据我简单写个过程,你看下是不是你想要的(这个存储过程可以直接执行,我在一个较为干净的数据库内部测试过了)。 CREATE OR REPLACE PROCEDURE PROC_FETCH_INFO IS --申请一个临时行对象,用于遍历时使用: V_ROW_INFO AAA%ROWTYPE; --定义一个表类型 TYPE TABLE_TYPE IS TABLE OF AAA%ROWTYPE INDEX BY BINARY_INTEGER; --根据表类型定义个表格 V_TABLE_INFO TABLE_TYPE; --便利时候的下标变量 v_index NUMBER; BEGIN --将你要遍历的数据装入: SELECT * BULK COLLECT INTO V_TABLE_INFO FROM AAA;
--正向循环一次。并输出数据 FOR v_index IN V_TABLE_INFO.FIRST .. V_TABLE_INFO.LAST LOOP V_ROW_INFO := V_TABLE_INFO(v_index); dbms_output.put_line(V_ROW_INFO.A1||' '||V_ROW_INFO.A2); END LOOP; dbms_output.put_line('================上面是正向循环输出,下面是反向循环输出了================='); --反向循环一次,并输出数据 v_index := V_TABLE_INFO.LAST; WHILE v_index>=V_TABLE_INFO.FIRST LOOP V_ROW_INFO := V_TABLE_INFO(v_index); dbms_output.put_line(V_ROW_INFO.A1||' '||V_ROW_INFO.A2); v_index := v_index-1; END LOOP; END PROC_FETCH_INFO; 测试运行结果: SQL> set serveroutput on; SQL> exec proc_fetch_info;1 aaa 2 vvv 3 edd ================上面是正向循环输出,下面是反向循环输出了================= 3 edd 2 vvv 1 aaaPL/SQL procedure successfully completed 不晓得你是不是这个要求。
DECLARE
cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
fdbk PLS_INTEGER;
BEGIN
DBMS_SQL.PARSE
(cur, 'SELECT * FROM emp WHERE deptno = 10 order by asc', DBMS_SQL.NATIVE); fdbk := DBMS_SQL.EXECUTE_CURSOR (cur);
FOR Nfetch IN 1 .. 5
LOOP
fdbk := DBMS_SQL.FETCH_ROWS (cur);
END LOOP;
DBMS_SQL.CLOSE_CURSOR (cur);DBMS_SQL.PARSE
(cur, 'SELECT * FROM emp WHERE deptno = 10 order by desc', DBMS_SQL.NATIVE); fdbk := DBMS_SQL.EXECUTE_CURSOR (cur);
FOR Nfetch IN 1 .. 5
LOOP
fdbk := DBMS_SQL.FETCH_ROWS (cur);
END LOOP;
DBMS_SQL.CLOSE_CURSOR (cur);
END;
open ref for
'select * from dual order by 字段 asc'open ref for
'select * from dual order by 字段 desc'
我这里假如你有一个表是(没有的话,用这个做下测试也行,呵呵):
CREATE TABLE AAA(A1 NUMBER,A2 VARCHAR2(20));
数据你可以手写几条进去就OK了,关键是循环了。此时遍历数据我简单写个过程,你看下是不是你想要的(这个存储过程可以直接执行,我在一个较为干净的数据库内部测试过了)。
CREATE OR REPLACE PROCEDURE PROC_FETCH_INFO
IS
--申请一个临时行对象,用于遍历时使用:
V_ROW_INFO AAA%ROWTYPE;
--定义一个表类型
TYPE TABLE_TYPE IS TABLE OF AAA%ROWTYPE INDEX BY BINARY_INTEGER;
--根据表类型定义个表格
V_TABLE_INFO TABLE_TYPE;
--便利时候的下标变量
v_index NUMBER;
BEGIN
--将你要遍历的数据装入:
SELECT *
BULK COLLECT INTO V_TABLE_INFO
FROM AAA;
--正向循环一次。并输出数据
FOR v_index IN V_TABLE_INFO.FIRST .. V_TABLE_INFO.LAST LOOP
V_ROW_INFO := V_TABLE_INFO(v_index);
dbms_output.put_line(V_ROW_INFO.A1||' '||V_ROW_INFO.A2);
END LOOP;
dbms_output.put_line('================上面是正向循环输出,下面是反向循环输出了=================');
--反向循环一次,并输出数据
v_index := V_TABLE_INFO.LAST;
WHILE v_index>=V_TABLE_INFO.FIRST LOOP
V_ROW_INFO := V_TABLE_INFO(v_index);
dbms_output.put_line(V_ROW_INFO.A1||' '||V_ROW_INFO.A2);
v_index := v_index-1;
END LOOP;
END PROC_FETCH_INFO;
测试运行结果:
SQL> set serveroutput on;
SQL> exec proc_fetch_info;1 aaa
2 vvv
3 edd
================上面是正向循环输出,下面是反向循环输出了=================
3 edd
2 vvv
1 aaaPL/SQL procedure successfully completed
不晓得你是不是这个要求。