今天为了解决一个查询结果想两次遍历的方法,去ORACLE官网文档中心 https://docs.oracle.com/en/database/oracle/,意外发现这个有意思的for语句。还是官方资料给力啊

遍历一个游标

DECLARE
CURSOR c1 IS
SELECT last_name, job_id FROM employees
WHERE job_id LIKE '%CLERK%' AND manager_id > 120
ORDER BY last_name;
BEGIN
FOR item IN c1
LOOP
DBMS_OUTPUT.PUT_LINE
('Name = ' || item.last_name || ', Job = ' || item.job_id);
END LOOP;
END;
/

遍历一个子查询

BEGIN
FOR item IN (
SELECT first_name || ' ' || last_name AS full_name,
salary * 10 AS dream_salary
FROM employees
WHERE ROWNUM <= 5
ORDER BY dream_salary DESC, last_name ASC
) LOOP
DBMS_OUTPUT.PUT_LINE
(item.full_name || ' dreams of making ' || item.dream_salary);
END LOOP;
END;
/

遍历列的列表

DECLARE
TYPE empcurtyp IS REF CURSOR;
TYPE namelist IS TABLE OF employees.last_name%TYPE;
TYPE sallist IS TABLE OF employees.salary%TYPE;
emp_cv empcurtyp;
names namelist;
sals sallist;
BEGIN
OPEN emp_cv FOR
SELECT last_name, salary FROM employees
WHERE job_id = 'SA_REP'
ORDER BY salary DESC; FETCH emp_cv BULK COLLECT INTO names, sals;
CLOSE emp_cv;
-- loop through the names and sals collections
FOR i IN names.FIRST .. names.LAST
LOOP
DBMS_OUTPUT.PUT_LINE
('Name = ' || names(i) || ', salary = ' || sals(i));
END LOOP;
END;
/

FOR循环使用关键字REVERSE倒着来

BEGIN
DBMS_OUTPUT.PUT_LINE ('upper_bound > lower_bound'); FOR i IN REVERSE 1..3 LOOP
DBMS_OUTPUT.PUT_LINE (i);
END LOOP; DBMS_OUTPUT.PUT_LINE ('upper_bound = lower_bound'); FOR i IN REVERSE 2..2 LOOP
DBMS_OUTPUT.PUT_LINE (i);
END LOOP; DBMS_OUTPUT.PUT_LINE ('upper_bound < lower_bound'); FOR i IN REVERSE 3..1 LOOP
DBMS_OUTPUT.PUT_LINE (i);
END LOOP;
END;
/

更有意思的游标里可以包含游标对象

DECLARE
TYPE emp_cur_typ IS REF CURSOR; emp_cur emp_cur_typ;
dept_name departments.department_name%TYPE;
emp_name employees.last_name%TYPE; CURSOR c1 IS
SELECT department_name,
CURSOR ( SELECT e.last_name
FROM employees e
WHERE e.department_id = d.department_id
ORDER BY e.last_name
) employees
FROM departments d
WHERE department_name LIKE 'A%'
ORDER BY department_name;
BEGIN
OPEN c1;
LOOP -- Process each row of query result set
FETCH c1 INTO dept_name, emp_cur;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Department: ' || dept_name); LOOP -- Process each row of subquery result set
FETCH emp_cur INTO emp_name;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('-- Employee: ' || emp_name);
END LOOP;
END LOOP;
CLOSE c1;
END;
/

Exit还可以这样用

DECLARE
s PLS_INTEGER := 0;
i PLS_INTEGER := 0;
j PLS_INTEGER;
BEGIN
<<outer_loop>>
LOOP
i := i + 1;
j := 0;
<<inner_loop>>
LOOP
j := j + 1;
s := s + i * j; -- Sum several products
EXIT inner_loop WHEN (j > 5);
EXIT outer_loop WHEN ((i * j) > 15);
END LOOP inner_loop;
END LOOP outer_loop;
DBMS_OUTPUT.PUT_LINE
('The sum of products equals: ' || TO_CHAR(s));
END;
/

continue也可以使用when

DECLARE
x NUMBER := 0;
BEGIN
LOOP -- After CONTINUE statement, control resumes here
DBMS_OUTPUT.PUT_LINE ('Inside loop: x = ' || TO_CHAR(x));
x := x + 1;
CONTINUE WHEN x < 3;
DBMS_OUTPUT.PUT_LINE
('Inside loop, after CONTINUE: x = ' || TO_CHAR(x));
EXIT WHEN x = 5;
END LOOP;
DBMS_OUTPUT.PUT_LINE (' After loop: x = ' || TO_CHAR(x));
END;
/

FOR循环中变量可以重名

BEGIN
<<outer_loop>>
FOR i IN 1..3 LOOP
<<inner_loop>>
FOR i IN 1..3 LOOP
IF outer_loop.i = 2 THEN
DBMS_OUTPUT.PUT_LINE
('outer: ' || TO_CHAR(outer_loop.i) || ' inner: '
|| TO_CHAR(inner_loop.i));
END IF;
END LOOP inner_loop;
END LOOP outer_loop;
END;
/

跳转语句GOTO的使用

DECLARE
p VARCHAR2(30);
n PLS_INTEGER := 37;
BEGIN
FOR j in 2..ROUND(SQRT(n)) LOOP
IF n MOD j = 0 THEN
p := ' is not a prime number';
GOTO print_now;
END IF;
END LOOP; p := ' is a prime number'; <<print_now>>
DBMS_OUTPUT.PUT_LINE(TO_CHAR(n) || p);
END;
/
DECLARE
v_last_name VARCHAR2(25);
v_emp_id NUMBER(6) := 120;
BEGIN
<<get_name>>
SELECT last_name INTO v_last_name
FROM employees
WHERE employee_id = v_emp_id; BEGIN
DBMS_OUTPUT.PUT_LINE (v_last_name);
v_emp_id := v_emp_id + 5; IF v_emp_id < 120 THEN
GOTO get_name;
END IF;
END;
END;
/

创建可以传参的游标

DECLARE
CURSOR c1 (job VARCHAR2, max_wage NUMBER) IS
SELECT * FROM employees
WHERE job_id = job
AND salary > max_wage;
BEGIN
FOR person IN c1('ST_CLERK', 3000)
LOOP
-- process data record
DBMS_OUTPUT.PUT_LINE (
'Name = ' || person.last_name || ', salary = ' ||
person.salary || ', Job Id = ' || person.job_id
);
END LOOP;
END;
/

两次遍历一个结果的最终解法

declare
cursor c1 is
select stockInfo from T_stock ORDER BY id;
BEGIN
FOR item IN c1
LOOP
DBMS_OUTPUT.PUT_LINE
('首次输出 = ' || item.stockInfo);
END LOOP;
FOR item IN c1
LOOP
DBMS_OUTPUT.PUT_LINE
('二次访问 = ' || item.stockInfo);
END LOOP;
END;

oracle的新发现for语句的更多相关文章

  1. oracle去掉重复记录语句

    oracle去掉重复记录语句   比如现在有一人员表 (表名:peosons) 若想将姓名.身份证号.住址这三个字段完全相同的记录查询出来 select p1.*   from persons  p1 ...

  2. oracle过程中动态语句实现

    oracle过程中动态语句实现 一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DD ...

  3. 说说oracle分页的sql语句

    说说oracle分页的sql语句,分排序和不排序两种. 当结果集不需要进行排序时,每页显示条数为:rowPerPage,当前页数为:currentPage. 1. 相对来说,这种查询速度会快一些,因为 ...

  4. oracle 多条执行语句同时执行

    oracle 多条执行语句同时执行:begin 语名一;语句二; end; 注意 如果写在C#里千万不要用@的方法然后语句里有回车 例: string strSql = "begin upd ...

  5. Oracle中分页查询语句

    Oracle分页查询语句使我们最常用的语句之一,下面就为您介绍的Oracle分页查询语句的用法,如果您对此方面感兴趣的话,不妨一看. Oracle分页查询语句基本上可以按照本文给出的格式来进行套用.O ...

  6. Oracle的分页查询语句优化

    Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. (一)   分页查询格式: SELECT * FROM  ( SELECT A.*, ROWNUM RN  FROM (SELECT ...

  7. ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句

    ORACLE-Kill 杀死正在执行的Oracle存储过程和死锁语句 存储过程 1.找到正在执行的存储过程的 sid ,serial# select   b.sid,b.SERIAL#,a.OBJEC ...

  8. Oracle数据库 基础SQL语句练习

    一.说明 第一次使用Oracle,想做一些练习,熟悉一些oracle. 表:使用的是scott用户,默认的表 具体表讲解,可以参考该文档:https://www.cnblogs.com/xjcheng ...

  9. imp导入时 出现IMP-00017:由于 ORACLE 错误 6550, 以下语句失败: 解决方法

    cmd命令下--执行imp命令时,出现IMP-00017:由于 ORACLE 错误 6550, 以下语句失败: 解决办法:在imp命令里加入 statistics=none (不导入数据库统计信息) ...

  10. Oracle执行SQL查询语句的步骤

    Oracle执行SQL查询语句的步骤 如果用户在SQL*Plus下输入了如下查询语句:SELECT * FROM dept: 查询语句的处理主要包括三个过程:编译(parse).执行(execute) ...

随机推荐

  1. C++学习笔记-Cherno C++系列

    21-23.[Cherno C++]C++中的静态(static) static变量只在编译单元内部链接 静态变量的作用域只在单个文件内 建议:在非特殊情况下,永远使用static定义全局变量以限制作 ...

  2. 使用SharpCompress压缩,tar.gz

    之前我们介绍了如何用SharpZipLib来打.tar.gz压缩包. 但是这个压缩软件有两个问题,一是代码比较多,压缩起来没有那么方便:二是压缩的.tar.gz在linux上解压时会有警告,需要跳过这 ...

  3. JDBC【4】-- SPI底层原理解析

    前面已经讲过SPI的基本实现原理了,demo也基本实现了,再来说说SPI. http://aphysia.cn/archives/jdbcspi 背景:SPI是什么? SPI,即是Service Pr ...

  4. mindoc 迁移

    1.备份数据库 mysqldump --databases mindoc_db > mindoc_db.sqlmysqldump -u USER_NAME -p PASSWORD [其他选项] ...

  5. JavaScript 样式操作

    1.类名操作 class类名以字符串的形式存储到标签和Dom元素的属性中,标签属性为class,Dom元素属性为className,两个属性是均支持读取和修改,修改其中的一个会同步至另一个属性 cla ...

  6. 精橙FPGA,一个承接FPGA代码设计的资深工程师团队。

    一.我们是谁 精橙FPGA,一个承接FPGA代码设计的资深工程师团队. 二.服务内容 面向在校学生.职场工程师等人员,提供FPGA入门指导和FPGA代码设计外包服务. 三.业务范围 主要提供Xilin ...

  7. WebSocket事件

    优点 双通信,减少延迟 四个主要的Web Socket API事件: ·打开 onopen 当在客户端和服务器建立连接,就会从Web Socket实例触发open事件.它被称为客户端和服务器之间的初始 ...

  8. Qt No Target Architecture

    在QT中引入processthreadsapi.h,如果出现 "No Target Architecture",需要在processthreadsapi.h前引入windows.h ...

  9. 介绍 MSTest Runner - CLI, Visual Studio 等更多

    介绍 MSTest Runner - CLI, Visual Studio 等更多 https://devblogs.microsoft.com/dotnet/introducing-ms-test- ...

  10. 使用 OpenXML 创建第一个 Word 文档

    using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; public class Op ...