今天为了解决一个查询结果想两次遍历的方法,去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. How to disable ipv6 in ubuntu

    To disable ipv6, you have to open /etc/sysctl.conf using any text editor and insert the following li ...

  2. 报错处理TypeError: can't multiply sequence by non-int of type 'float'

    在练习格式化输出时出现错误TypeError: can't multiply sequence by non-int of type 'float' 为什么会出现TypeError:不能将序列乘以'f ...

  3. 全新向量数据库SQL Server 2025:带你迈入AI驱动的数据未来

    全新向量数据库SQL Server 2025:带你迈入AI驱动的数据未来 上次大家下单的<微软憋大招:SQL Server + Copilot = 地表最强AI数据库!> 抱怨迟迟没有发货 ...

  4. JConsole 远程监控Tomcat服务

    JConsole 远程监控Tomcat服务 1.概述 JConsole是一个基于JMX的GUI工具,用于连接正在运行的JVM,不过此JVM需要使用可管理的模式启动.如果要把一个应用以可管理的形式启动, ...

  5. 什么是静态(static)?什么是静态方法,静态变量,静态块和静态类?

    本文由 ImportNew - 唐小娟 翻译自 Journaldev.如需转载本文,请先参见文章末尾处的转载要求. static是Java中的一个关键字,我们不能声明普通外层类或者包为静态的.stat ...

  6. 根据Xml节点名获取Xpath

    我们经常使用Xpath去获取Xml中某个节点的值,但是有时候我们需要反过来,根据Xml的节点名来获取对应的Xpath. 找了一下,几乎所有的Xml库都没有提供类似的功能,这里我们就简单说一说这玩意咋实 ...

  7. CCPC Henan Provincial Contest 2020

    CCPC Henan Provincial Contest 2020 Problem B. 广告投放 n集节目按顺序播出,节目组决定在某些节目中投放广告,节目最初播出时有m名观众,若\(i\)集投放广 ...

  8. OceanBase 的探索与实践

    作者:来自 vivo 互联网数据库团队- Xu Shaohui 本文总结了目前我们遇到的痛点问题并通过 OceanBase 的技术方案解决了这些痛点问题,完整的描述了 OceanBase 的实施落地, ...

  9. 在CodeBolcks+wxWidgets下的C++编程教程——用向导创建一个wxWidgets项目(xTetris)

    0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程.我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识. 了解我编写教 ...

  10. Git使用备忘录

    定义 分布式版本控制工具 Git四个工作区域 工作区(Working Directory):就是你平时存放项目代码的地方 暂存区(Stage/Index):用于临时存放你的改动,事实上它只是一个文件, ...