- 浏览: 362639 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (511)
- AgileMethodology (4)
- RDBMS (32)
- NoSQL (16)
- Java (27)
- Python (28)
- Maven (15)
- Linux (27)
- CommonUtils (13)
- IDE (8)
- JavaScript (17)
- jQuery (2)
- OSGi (2)
- JavaWeb (5)
- Spring (37)
- Struts2 (3)
- ORM (13)
- Ant (1)
- apache-tiles (1)
- FreeMarker (2)
- JSON (8)
- XML (1)
- JUnit (3)
- Lucene (1)
- Web Service (9)
- Design Pattern (13)
- Algorithm (21)
- JVM (14)
- Hadoop (16)
- Spark (5)
- Scala (31)
- Git (4)
- Server (3)
- Node.js (18)
- Concurrent (42)
- Lock (9)
- Collections (3)
- Network (11)
- MicroService (7)
- Docker (13)
- FP (20)
- spring.io (2)
- ELK (1)
- Kafka (5)
最新评论
SQL语言是面向集合的,其结果一般是集合量(多条记录),而PL/SQL语言的变量一般是标量,其一组变量只能存放一条记录。所以仅仅使用变量并不能完全满足SQL语句向应用程序输出数据的要求。因为查询结果的记录数是不确定的,事先也就不知道要声明几个变量。为此,在PL/SQL中引入了游标(cursor)的概念,用游标来协调这两种不同的处理方式。
在PL/SQL块中执行select, insert, update, delete语句时,Oracle会在内存中为其分配上下文区(Context Area),即一个缓存区。游标是指向该区的一个指针,或是命名一个工作区(Work Area),或是一种结构化数据类型。它为应用程序提供了一种对具有多行数据的查询结果集中的每一行数据分别进行单独处理的方法,是设计嵌入了SQL语句的应用程序的常用编程方式。
游标分为显式游标、隐式游标两种。隐式游标是Oracle为所有数据语句(包括只返回单行数据的查询语句)自动声明和操作的一种游标;显式游标是由用户声明和操作的一种游标。
在每个用户会话中,可以同时打开多个游标,其数量由数据库初始化参数文件中的OPEN_CURSORS参数定义。
显式游标
无论是显式游标、隐式游标,均有%ISOPEN、%FOUND、%NOTFOUND、%ROWCOUNT四种属性。它们描述与游标操作相关的DML语句的执行情况。游标属性只能用在PL/SQL的流程控制语句内,而不能用在SQL语句内。
--example 1 : 声明一个没有参数没有返回值的游标c1
DECLARE v_ename emp.ename%TYPE; v_job emp.job%TYPE; CURSOR c1 IS SELECT ename, job FROM emp WHERE deptno = 20; BEGIN OPEN c1; LOOP FETCH c1 INTO v_ename, v_job; IF c1%FOUND THEN DBMS_OUTPUT.put_line (v_ename || '的岗位是' || v_job); ELSE DBMS_OUTPUT.put_line ('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c1; END; /
--example 2 : 声明一个有参数没有返回值的游标c2
DECLARE v_ename emp.ename%TYPE; v_hiredate emp.hiredate%TYPE; CURSOR c2 (c_deptno NUMBER, c_job VARCHAR2) IS SELECT ename, hiredate FROM emp WHERE deptno = c_deptno AND job = c_job; BEGIN OPEN c2 (20, 'MANAGER'); LOOP FETCH c2 INTO v_ename, v_hiredate; IF c2%FOUND THEN DBMS_OUTPUT.put_line (v_ename || '的雇佣日期是 ' || v_hiredate); ELSE DBMS_OUTPUT.put_line ('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c2; END; /
--example 3 : 声明一个有参数有返回值的游标c3
DECLARE TYPE emp_record_type IS RECORD ( ename emp.ename%TYPE, hiredate emp.hiredate%TYPE ); v_emp_record emp_record_type; CURSOR c3 (c_deptno NUMBER, c_job VARCHAR2) RETURN emp_record_type IS SELECT ename, hiredate FROM emp WHERE deptno = c_deptno AND job = c_job; BEGIN OPEN c3 (c_job => 'MANAGER', c_deptno => 20); --OPEN c3 (c_deptno => 20, c_job => 'MANAGER'); --OPEN c3 (20, 'MANAGER'); LOOP FETCH c3 INTO v_emp_record; IF c3%FOUND THEN DBMS_OUTPUT.put_line ( v_emp_record.ename || '的雇佣日期是' || v_emp_record.hiredate); ELSE DBMS_OUTPUT.put_line ('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c3; END; /
--example 4 : 声明一个有参数没有返回值的游标c4,使用%ROWTYPE属性不仅可以基于表定义记录变量,也可以基于游标定义记录变量(这比声明记录类型变量要方便,不容易出错)
DECLARE CURSOR c4 (c_deptno NUMBER, c_job VARCHAR2) IS SELECT ename f_ename, hiredate FROM emp WHERE deptno = c_deptno AND job = c_job; v_emp_record c4%ROWTYPE; BEGIN OPEN c4 (20, 'ANALYST'); LOOP FETCH c4 INTO v_emp_record; IF c4%FOUND THEN DBMS_OUTPUT.put_line ( v_emp_record.f_ename || '的雇佣日期是' || v_emp_record.hiredate); ELSE DBMS_OUTPUT.put_line ('已经处理完结果集了'); EXIT; END IF; END LOOP; CLOSE c4; END; /
隐式游标
隐式游标是由PL/SQL控制的。当执行一条DML语句或SELECT...INTO语句时,都会创建一个隐式游标。隐式游标的名称是SQL。不能对SQL游标显式地执行OPEN、FETCH、CLOSE语句。Oracle隐式地打开、提取、并总是自动关闭SQL游标。
当使用SELECT语句时,SQL游标一次只能返回一行或没有返回行(对应于NO_DATA_FOUND异常),如果返回多行,就会产生TOO_MANY_ROWS异常,这时就应该使用显示游标来处理了。当使用INSERT、UPDATE、DELETE时,SQL游标可以处理多行。
--example 5 : 通过访问隐式游标SQL的%ROWCOUNT属性来了解修改了多少行
DECLARE v_rows NUMBER; BEGIN UPDATE emp SET comm = 1234 WHERE deptno = 20; v_rows := SQL%ROWCOUNT; DBMS_OUTPUT.put_line ('更新了 ' || v_rows || ' 个雇员的奖金'); ROLLBACK; END; /
游标FOR循环
为了简化游标操作,PL/SQL语言提供了游标FOR循环语句。一个游标FOR循环可以隐含地实现OPEN、FETCH、CLOSE游标以及循环处理结果集的功能。其步骤是:
1.当进入循环时,自动打开一个已经声明的游标,并提取第一行游标数据。
2.当处理完当前所提取的数据而进入下一次循环时,自动提取下一行游标数据。
3.当提取完结果集中的所有数据行后结束循环,并自动关闭游标。
--example 6 : 使用游标FOR循环来查询显示多行记录数据集
DECLARE CURSOR c1 (c_empno NUMBER DEFAULT 7788) IS SELECT ename, hiredate FROM emp WHERE empno = c_empno; BEGIN DBMS_OUTPUT.put_line ('----给c_empno传递参数7369时:----'); FOR c1_record IN c1 (7369) LOOP DBMS_OUTPUT.put_line ( c1_record.ename || ' 的雇佣日期是 ' || c1_record.hiredate); END LOOP; DBMS_OUTPUT.put_line ('----给c_empno传递参数7788时:----'); FOR c1_record IN c1 LOOP DBMS_OUTPUT.put_line ( c1_record.ename || ' 的雇佣日期是 ' || c1_record.hiredate); END LOOP; END; /
使用游标更新或删除数据
要求游标查询语句中必须使用FOR UPDATE子句,以便在打开游标时锁定游标结果集在数据表中对应的数据行,从而不被其他用户更新或删除,这样才能更新或删除被锁定的数据行。
使用FOR UPDATE选项的游标查询语句的语法格式为:
SELECT column_list FROM table_list FOR UPDATE [NOWAIT];
使用FOR UPDATE打开游标之后,就可以在UPDATE,DELETE语句中使用WHERE CURRENT OF子句,修改或删除游标结果集中当前行所对应的数据库表中的数据行。其语法格式为:
不带WHERE条件的UPDATE语句或DELETE语句 WHERE CURRENT OF cursor_name;
--example 7
DECLARE v_emp_record emp%ROWTYPE; CURSOR c1 IS SELECT * FROM emp FOR UPDATE; BEGIN OPEN c1; LOOP FETCH c1 INTO v_emp_record; EXIT WHEN c1%NOTFOUND; IF v_emp_record.empno = 7788 THEN UPDATE emp SET comm = 1234 WHERE CURRENT OF c1; END IF; END LOOP; COMMIT; CLOSE c1; END;
如果将其中的UPDATE语句更改为:
DELETE FROM emp WHERE CURRENT OF c1;就会将emp表中empno等于7788的记录删除。
发表评论
-
MySQL UNSIGNED
2019-06-26 13:31 377原创转载请注明出处:https://agilestyle. ... -
MySQL索引最左匹配原则
2018-11-14 12:44 2620原创转载请注明出处:http://agilestyle.i ... -
MySQL SQL Create demo
2018-10-22 15:10 381ddl demo CREATE TABLE IF NOT ... -
(转)MySQL Explain详解
2018-09-30 13:16 381作者:陆炫志 出处:xuanzhi的博客 http:// ... -
Mac上安装MySQL后zsh: command not found: mysql
2018-08-19 21:20 4069原创转载请注明出处:http://agilestyle.i ... -
MySQL key值的含义
2017-09-25 21:05 663PRI — 主键约束; UNI — 唯一约束; MU ... -
SQL常见笔试题
2017-09-06 23:00 385原创转载请注明出处:http://agilestyle.i ... -
MySQL扩展
2017-08-23 21:50 487原创转载请注明出处 ... -
表级锁、行级锁、页面锁
2017-04-17 21:30 491原创转载请注明出处 ... -
Oracle优化常见术语
2017-04-02 23:03 449原创转载请注明出处:http://agilestyle.i ... -
Oracle分区
2017-04-02 22:03 409原创转载请注明出处:http://agilestyle.i ... -
MySQL分区
2017-02-24 14:11 375原创转载请注明出处:http://agilestyle.i ... -
Oracle常见术语、操作、区别
2017-02-22 20:55 843原创转载请注明出处:http://agilestyle.i ... -
ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
2017-02-15 17:03 471原创转载请注明出处:http://agilestyle.i ... -
SQL UNION 操作符
2016-11-24 16:22 680原创转载请注明出处 ... -
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
2016-09-02 10:16 374use query below to check activ ... -
MySQL压缩版安装配置
2016-05-18 23:29 614原创装载请注明出处:http://agilestyle.i ... -
综合数据和分组函数
2016-01-30 21:41 578desc emp; COUNT函数 selec ... -
1NF、2NF、3NF
2016-01-28 02:53 409第一范式: 所有的键属性(列)都已定义 没有任何重复组 ... -
ORACLE11gR2完全卸载(转)
2015-12-19 16:45 15251. 停止“服务”中所有的ORCLE服务。 ...
相关推荐
Oracle PL/SQL是一种强大的编程语言,它将数据库管理和应用程序逻辑紧密结合起来,是Oracle数据库系统中的核心组件之一。这本书“Oracle PL/SQL实例编程”显然旨在深入讲解如何利用PL/SQL进行实际开发工作,通过实例...
The new PL/SQL Clipboard is a dockable tool that stores the history of all SQL and PL/SQL code you copy to the Windows clipboard, so that you can paste the clipboard item again in the future....
The example above filters for Valid objects that have the word DeptRecord in the PL/SQL source. Other enhancements include: Indexes and constraints can now be renamed Triggers can now be created in ...
The new PL/SQL Clipboard is a dockable tool that stores the history of all SQL and PL/SQL code you copy to the Windows clipboard, so that you can paste the clipboard item again in the future....
The new PL/SQL Clipboard is a dockable tool that stores the history of all SQL and PL/SQL code you copy to the Windows clipboard, so that you can paste the clipboard item again in the future....
Pro*C/C++ 是一种集成在C或C++编程语言中的预处理器,它允许程序员直接在源代码中嵌入PL/SQL语句,用于与Oracle数据库进行交互。这种编程方式提供了高效且灵活的数据库访问手段,特别适合于开发与Oracle数据库紧密...
The new PL/SQL Clipboard is a dockable tool that stores the history of all SQL and PL/SQL code you copy to the Windows clipboard, so that you can paste the clipboard item again in the future....
The new PL/SQL Clipboard is a dockable tool that stores the history of all SQL and PL/SQL code you copy to the Windows clipboard, so that you can paste the clipboard item again in the future....
The new PL/SQL Clipboard is a dockable tool that stores the history of all SQL and PL/SQL code you copy to the Windows clipboard, so that you can paste the clipboard item again in the future....
1. **过程(Procedure)**:过程是存储在数据库中的PL/SQL代码块,可以执行特定任务。创建过程的SQL命令是`CREATE OR REPLACE PROCEDURE`,例如: ```sql CREATE OR REPLACE PROCEDURE my_procedure (param1 IN ...
5. **运行程序**: 编译完成后,可以通过`./example`来运行程序,连接到数据库并执行预定义的PL/SQL块。 **四、示例代码结构** 一个简单的Oracle PRO*C程序可能包含以下元素: ```c #include #include "example.pc...
- The script to which the character belongs is supported by the JRE installation on which SQL Developer is running � for example, appropriate fonts are available � and - The script does not ...
Oracle存储过程是数据库管理系统Oracle中的一种重要特性,用于封装一系列SQL和PL/SQL语句,以便重复使用和提高代码效率。下面将详细讲解Oracle存储过程的基本语法和注意事项。 首先,创建一个存储过程的基本语法...
- **`pl_sql_subprogram_body`**: PL/SQL过程体,包含具体的执行逻辑。 ##### 示例 ```sql CREATE OR REPLACE PROCEDURE sam.credit ( acc_no IN NUMBER, amount IN NUMBER ) AS BEGIN UPDATE accounts SET ...
此外,Oracle的PL/SQL语言允许编写存储过程和触发器,实现更复杂的业务逻辑。例如,创建一个检查新插入Email是否有效的触发器: ```sql CREATE OR REPLACE TRIGGER CheckEmail BEFORE INSERT ON Employees FOR EACH...
SQL & PL/SQL ##### 1.1 查询特殊字符,如通配符%与_ **问题**: 如何在Oracle中查询包含特殊字符如通配符%与_的数据? **解答**: 在Oracle中查询包含特殊字符如通配符%与_的数据时,需要使用转义字符来避免这些...
首先,Oracle存储过程是一种预编译的SQL和PL/SQL代码块,可以在数据库服务器端执行,提供了一种封装业务逻辑的方式。而游标(Cursor)在数据库中用于处理单行数据,它允许我们按需逐行读取查询结果,而不必一次性...
**存储过程**是在Oracle数据库中预先编译并存储的一组SQL语句或PL/SQL代码块。它们可以接受输入参数,执行一系列操作,并返回结果。存储过程提高了代码的重用性、性能以及安全性。**存储过程包**则是一种组织多个...