- 浏览: 142546 次
文章分类
最新评论
-
whwh13764799336:
[color=red][/color]
出现Connection reset by peer: socket write error问题的原因 -
aihua_girl:
good
第三章 PL/SQL数据类型 -
haitunwan:
<result name="success ...
出现Connection reset by peer: socket write error问题的原因 -
ynial:
对接口使用注释 好吗?
spring 中的事务小结 -
poshboytl:
问题应该出在session中
由于迭代前session中存放的 ...
在学习<应用Rails进行敏捷Web开发>遇到问题
十一、避免集合异常
大多情况下,如果我们引用了一个集合中不存在的元素,PL/SQL就会抛出一个预定义异常。例如:
DECLARE
TYPE numlist IS TABLE OF NUMBER;
nums numlist; -- atomically null
BEGIN
/* Assume execution continues despite the raised exceptions. */
nums(1) := 1; -- raises COLLECTION_IS_NULL (1)
nums := numlist(1, 2); -- initialize table
nums(NULL) := 3; -- raises VALUE_ERROR (2)
nums(0) := 3; -- raises SUBSCRIPT_OUTSIDE_LIMIT (3)
nums(3) := 3; -- raises SUBSCRIPT_BEYOND_COUNT (4)
nums.DELETE(1); -- delete element 1
IF nums(1) = 1 THEN
... -- raises NO_DATA_FOUND (5)
END;
第一句,嵌套表是空的;第二句,下标为空;三四句,下标超出合法范围之外;第五句,下标指向了一个被删除的元素。下表是一些异常情况的说明:
COLLECTION_IS_NULL | 调用一个空集合的方法 |
NO_DATA_FOUND | 下标索引指向一个被删除的元素,或是关联数组中不存在的元素 |
SUBSCRIPT_BEYOND_COUNT | 下标索引值超过集合中的元素个数 |
SUBSCRIPT_OUTSIDE_LIMIT | 下标索引超过允许范围之外 |
VALUE_ERROR | 下标索引值为空,或是不能转换成正确的键类型。当键被定义在 PLS_INTEGER的范围内,而下标索引值超过这个范围就可能抛 出这个异常 |
在某些情况下,如果我们为一个方法传递了一个无效的下标,并不会抛出异常。例如在使用DELETE方法的时候,我们向它传递NULL,它只是什么都没做而已。同样,用新值替换被删除的元素也不会引起NO_DATA_FOUND异常,如下例:
DECLARE
TYPE numlist IS TABLE OF NUMBER;
nums numlist := numlist(10, 20, 30); -- initialize table
BEGIN
nums.DELETE(-1); -- does not raise SUBSCRIPT_OUTSIDE_LIMIT
nums.DELETE(3); -- delete 3rd element
DBMS_OUTPUT.put_line(nums.COUNT); -- prints 2
nums(3) := 30; -- allowed; does not raise NO_DATA_FOUND
DBMS_OUTPUT.put_line(nums.COUNT); -- prints 3
END;
打包集合类型和本地集合类型总是不兼容的。假设我们想调用下面的打包过程:
CREATE PACKAGE pkg1 AS
TYPE NumList IS VARRAY(25) OF NUMBER(4);
PROCEDURE delete_emps (emp_list NumList);
END pkg1;
CREATE PACKAGE BODY pkg1 AS
PROCEDURE delete_emps (emp_list NumList) IS ...
...
END pkg1;
在运行下面PL/SQL块时,第二个过程调用会因参数的数量或类型错误(wrong number or types of arguments error)而执行失败。这是因为打包VARRAY和本地VARRAY类型不兼容,虽然它们的定义形式都是一样的:
DECLARE
TYPE numlist IS VARRAY(25) OF NUMBER(4);
emps pkg1.numlist := pkg1.numlist(7369, 7499);
emps2 numlist := numlist(7521, 7566);
BEGIN
pkg1.delete_emps(emps);
pkg1.delete_emps(emps2); -- causes a compilation error
END;十二、使用集合批量绑定减少循环开销
如下图所示,PL/SQL引擎会执行过程化语句,但它把SQL语句发送给SQL引擎处理,然后SQL引擎把处理的结果返回给PL/SQL引擎。
PL/SQL和SQL引擎间的频繁切换会大大降低效率。典型的情况就是在一个循环中反复执行SQL语句。例如,下面的DELETE语句就会在FOR循环中被多次发送到SQL引擎中去:
DECLARE
TYPE numlist IS VARRAY(20) OF NUMBER;
depts numlist := numlist(10, 30, 70); -- department numbers
BEGIN
...
FOR i IN depts.FIRST .. depts.LAST LOOP
DELETE FROM emp
WHERE deptno = depts(i);
END LOOP;
END;
这种情况下,如果SQL语句影响了四行或更多行时,使用批量绑定就会显著地提高性能。
1、批量绑定如何提高性能
用SQL语句中为PL/SQL变量赋值称为绑定,PL/SQL绑定操作可以分为三种:
- 内绑定(in-bind):用INSERT或UPDATE语句将PL/SQL变量或主变量保存到数据库。
- 外绑定(out-bind):通过INSERT、UPDATE或DELETE语句的RETURNING子句的返回值为PL/SQL变量或主变量赋值。
- 定义(define):使用SELECT或FETCH语句为PL/SQL变量或主变量赋值。
DML语句可以一次性传递集合中所有的元素,这个过程就是批量绑定。如果集合有20个元素,批量绑定的一次操作就相当于执行20次SELECT、 INSERT、UPDATE或DELETE语句。这项技术是靠减少PL/SQL和SQL引擎间的切换次数来提高性能的。要对INSERT、UPDATE和 DELETE语句使用批量绑定,就要用PL/SQL的FORALL语句。
如果要在SELECT语句中使用批量绑定,我们就要在SELECT语句后面加上一个BULK COLLECT子句来代替INTO子句。
- 例一:对DELETE语句应用批量绑定
下面的DELETE语句只往SQL引擎中发送一次,即使是执行了三次DELETE操作:
DECLARE
TYPE numlist IS VARRAY(20) OF NUMBER;
depts numlist := numlist(10, 30, 70); -- department numbers
BEGIN
FORALL i IN depts.FIRST .. depts.LAST
DELETE FROM emp
WHERE deptno = depts(i);
END;
- 例二:对INSERT语句应用批量绑定
下例中,我们把5000个零件编号和名称放到索引表中。所有的表元素都向数据库插入两次:第一次使用FOR循环,然后使用FORALL语句。实际上,FORALL版本的代码执行速度要比FOR语句版本的快得多。
SQL> SET SERVEROUTPUT ON
SQL> CREATE TABLE parts (pnum NUMBER(4), pname CHAR(15));
Table created.
SQL> GET test.sql
1 DECLARE
2 TYPE NumTab IS TABLE OF NUMBER(4) INDEX BY BINARY_INTEGER;
3 TYPE NameTab IS TABLE OF CHAR(15) INDEX BY BINARY_INTEGER;
4 pnums NumTab;
5 pnames NameTab;
6 t1 NUMBER(5);
7 t2 NUMBER(5);
8 t3 NUMBER(5);
9
10
11 BEGIN
12 FOR j IN 1..5000 LOOP -- load index-by tables
13 pnums(j) := j;
14 pnames(j) := 'Part No. ' || TO_CHAR(j);
15 END LOOP;
16 t1 := dbms_utility.get_time;
17 FOR i IN 1..5000 LOOP -- use FOR loop
18 INSERT INTO parts VALUES (pnums(i), pnames(i));
19 END LOOP;
20 t2 := dbms_utility.get_time;
21 FORALL i IN 1..5000 -- use FORALL statement
22 INSERT INTO parts VALUES (pnums(i), pnames(i));
23 get_time(t3);
24 dbms_output.put_line('Execution Time (secs)');
25 dbms_output.put_line('---------------------');
26 dbms_output.put_line('FOR loop: ' || TO_CHAR(t2 - t1));
27 dbms_output.put_line('FORALL: ' || TO_CHAR(t3 - t2));
28* END;
SQL> /
Execution Time (secs)
---------------------
FOR loop: 32
FORALL: 3十三、使用FORALL语句
关键字FORALL能让PL/SQL引擎在将集合发送到SQL引擎之前,批量导入集合元素。虽然FORALL也包含了迭代的模式,但它并不是简单的FOR循环。它的使用语法如下:
FORALL index IN lower_bound..upper_bound
sql_statement;index只能在FORALL语句块内作为集合下标使用。SQL语句必须是引用了集合元素的INSERT、UPDATE或DELETE语句。bound的有效范围是连续的索引号。在这个范围内,SQL引擎为每个索引号执行一次SQL语句。
- 例一:使用FORALL操作集合的部分内容
如下例所示,FORALL循环的边界值可作用于集合的部分内容,不必是全部的元素:
DECLARE
TYPE numlist IS VARRAY(10) OF NUMBER;
depts numlist := numlist(20, 30, 50, 55, 57, 60, 70, 75, 90, 92);
BEGIN
FORALL j IN 4 .. 7 -- bulk-bind only part of varray
UPDATE emp
SET sal = sal * 1.10
WHERE deptno = depts(j);
END;
- 例二:使用集合下标索引的批量绑定
SQL语句能引用一个以上的集合。但是PL/SQL引擎的批量绑定只能为一个集合添加下标索引。所以,在下面的例子中,对于传递给函数median的集合sals,并没有使用到批量绑定。
FORALL i IN 1..20
INSERT INTO emp2 VALUES (enums(i), names(i), median(sals), ...);
- 例三:使用FORALL为对象表添加数据
除了关系表之外,FORALL语句还可以操作对象表,如下例所示:
CREATE TYPE pnum AS OBJECT(
n NUMBER
);
/
CREATE TABLE partno OF pnum;
DECLARE
TYPE numtab IS TABLE OF NUMBER;
nums numtab := numtab(1, 2, 3, 4);
TYPE pnumtab IS TABLE OF pnum;
pnums pnumtab := pnumtab(pnum(1), pnum(2), pnum(3), pnum(4));
BEGIN
FORALL i IN pnums.FIRST .. pnums.LAST
INSERT INTO partno
VALUES (pnums(i));
FORALL i IN nums.FIRST .. nums.LAST
DELETE FROM partno
WHERE n = 2 * nums(i);
FORALL i IN nums.FIRST .. nums.LAST
INSERT INTO partno
VALUES (100 + nums(i));
END;1、FORALL语句对回滚的影响
在FORALL语句中,如果SQL语句引起了一个未捕获异常,以前对数据库的所有操作都会被回滚。但是,如果我们捕获到被抛出的异常并加以处理,此次之前的操作就不会被回滚。举一个例子,假设我们创建了数据表用来存储部门编号和职别:
CREATE TABLE emp2 (deptno NUMBER(2), job VARCHAR2(15)); 下一步,为刚才建立的数据表添加一些记录:
INSERT INTO emp2 VALUES(10, 'Clerk');
INSERT INTO emp2 VALUES(10, 'Clerk');
INSERT INTO emp2 VALUES(20, 'Bookkeeper'); -- 10-char job title
INSERT INTO emp2 VALUES(30, 'Analyst');
INSERT INTO emp2 VALUES(30, 'Analyst');然后,我们用下面的UPDATE语句为特定的职称加上七位字符串' (temp)':
DECLARE
TYPE numlist IS TABLE OF NUMBER;
depts numlist := numlist(10, 20, 30);
BEGIN
FORALL j IN depts.FIRST .. depts.LAST
UPDATE emp2
SET job = job || ' (temp)'
WHERE deptno = depts(j);
-- raises a "value too large" exception
EXCEPTION
WHEN OTHERS THEN
COMMIT;
END;SQL引擎会执行UPDATE语句三次,第一次成功,但在第二次会因字符串值'Bookkeeper (temp)'太长而无法赋给job字段,所以就会执行失败。这种情况下,只有第二条语句回滚。
只要有SQL语句抛出异常,FORALL语句就会终止执行。在上面的例子中,第二个UPDATE语句抛出了异常,第三个语句就不会被执行了。
2、使用%BULK_ROWCOUNT属性来计算FORALL语句所影响到的行数
处理SQL数据操作语句时,SQL引擎会隐式地打开一个名为SQL的游标。这个游标的标量属性%FOUND、%ISOPEN、%NOTFOUND和%ROWCOUNT,能够提供最近一次执行的SQL数据操作语句信息。
SQL游标还有一个专门为FORALL设计的复合属性%BULK_ROWCOUNT。这个属性有些像索引表。它的第i个元素保存了第i次的 INSERT或UPDATE或DELETE语句所影响到的行数。如果第i次操作没有行被影响,%BULK_ROWCOUNT(i)就返回零。下面来看一个例子:
DECLARE
TYPE numlist IS TABLE OF NUMBER;
depts numlist := numlist(10, 20, 50);
BEGIN
FORALL j IN depts.FIRST .. depts.LAST
UPDATE emp
SET sal = sal * 1.10
WHERE deptno = depts(j);
-- Did the 3rd UPDATE statement affect any rows?
IF SQL%BULK_ROWCOUNT(3) = 0 THEN ...
END;FORALL语句和%BULK_ROWCOUNT属性使用同样的下标索引。如果FORALL使用下标索引的范围在5到10的话,那么% BULK_ROWCOUNT的也是。对于插入操作来说,%BULK_ROWCOUNT的结果一般是1,但是对于INSERT ... SELECT这样的结构来说,%BULK_ROWCOUNT的值就有可能大于1。例如,下面的FORALL语句在循环插入数据的过程中,每次插入的行的个数都是不固定的,%BULK_ROWCOUNT可以记录每次插入的行数:
SET SERVEROUTPUT ON;
DECLARE
TYPE num_tab IS TABLE OF NUMBER;
deptnums num_tab;
BEGIN
SELECT deptno
BULK COLLECT INTO deptnums
FROM dept;
FORALL i IN 1 .. deptnums.COUNT
INSERT INTO emp_by_dept
SELECT empno, deptno
FROM emp
WHERE deptno = deptnums(i);
FOR i IN 1 .. deptnums.COUNT LOOP
-- Count how many rows were inserted for each department; that is,
-- how many employees are in each department.
DBMS_OUTPUT.put_line( 'Dept '
|| deptnums(i)
|| ': inserted '
|| SQL%BULK_ROWCOUNT(i)
|| ' records');
END LOOP;
DBMS_OUTPUT.put_line('Total records inserted =' || SQL%ROWCOUNT);
END;
/我们还可以在批量绑定中使用标量属性%FOUND、%ISOPEN、%NOTFOUND和%ROWCOUNT。例如,%ROWCOUNT会返回所有的SQL语句处理的总行数。
%FOUND和%NOTFOUND只是针对最后一次SQL语句执行的结果。但是,我们可以利用%BULK_ROWCOUNT来推断出每个单独语句的处理结果。当%BULK_ROWCOUNT(i)为零时,%FOUND和%NOTFOUND就分别为FALSE和TRUE。
3、使用%BULK_EXCEPTIONS属性来控制FORALL异常
PL/SQL为FORALL语句提供了一个异常控制机制。这个机制能让使用批量绑定的操作保存异常信息并不中断地执行直至完成操作。
为了让批量绑定在错误发生时还能够继续执行,需要在FORALL语句中添加关键字SAVE EXCEPTIONS,语法如下:
FORALL index IN lower_bound..upper_bound SAVE EXCEPTIONS
{insert_stmt | update_stmt | delete_stmt}执行时发生的所有的异常信息都会保存在新的游标属性%BULK_EXCEPTIONS中。%BULK_EXCEPTIONS是一个记录类型集合,每个记录有两个域,分别是ERROR_INDEX和ERROR_CODE,前者保存FORALL语句的"循环"索引,后者保存对应的Oracle错误编号。
存放在%BULK_EXCEPTIONS中的值总是与最近一次FORALL语句执行的结果相关,异常的个数存放在%BULK_EXCEPTIONS 的COUNT属性中,%BULK_EXCEPTIONS有效的下标索引范围在1到%BULK_EXCEPTIONS.COUNT之间。
我们不使用关键字SAVE EXCEPTIONS时,如果异常发生,FORALL语句就会停止执行,SQL%BULK_EXCEPTIONS.COUNT的值就是一,SQL% BULK_EXCEPTIONS中只包含一条记录;如果没有异常发生,SQL%BULK_EXCEPTIONS.COUNT的值就是零。下面的例子演示了 %BULK_EXCEPTIONS的一些用法:
DECLARE
TYPE numlist IS TABLE OF NUMBER;
num_tab numlist := numlist(10, 0, 11, 12, 30, 0, 20, 199, 2, 0, 9, 1);
ERRORS NUMBER;
dml_errors EXCEPTION;
PRAGMA EXCEPTION_INIT(dml_errors, -24381);
BEGIN
FORALL i IN num_tab.FIRST .. num_tab.LAST SAVE EXCEPTIONS
DELETE FROM emp
WHERE sal > 500000 / num_tab(i);
EXCEPTION
WHEN dml_errors THEN
ERRORS := SQL%BULK_EXCEPTIONS.COUNT;
DBMS_OUTPUT.put_line('Number of errors is ' || ERRORS);
FOR i IN 1 .. ERRORS LOOP
DBMS_OUTPUT.put_line( 'Error '
|| i
|| ' occurred during '
|| 'iteration '
|| SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
DBMS_OUTPUT.put_line( 'Oracle error is '
|| SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
END LOOP;
END;例子中,PL/SQL在i等于2、6、10时会抛出预定义异常ZERO_DIVIDE。当批量绑定完成时,SQL% BULK_EXCEPTIONS.COUNT就会返回3,SQL%BULK_EXCEPTIONS的内容就是(2,1476),(6,1476)和 (10,1476)。如果想得到错误消息,我们可以把SQL%BULK_EXCEPTIONS(i).ERROR_CODE传递给错误报告函数 SQLERRM,这样就能得到下面的输出结果:
Number of errors is 3
Error 1 occurred during iteration 2
Oracle error is ORA-01476: divisor is equal to zero
Error 2 occurred during iteration 6
Oracle error is ORA-01476: divisor is equal to zero
Error 3 occurred during iteration 10
Oracle error is ORA-01476: divisor is equal to zero
发表评论
-
Windows下面配置Oracle10g即时客户端
2009-09-30 13:54 1925一、安装指导 安装步骤: 1. 为您的平台下载相应的即 ... -
Oracle PL/SQL 过程调试的输出方法
2008-04-24 10:29 21311.最基本的DBMS_OUTPUT.PUT_LINE()方法。 ... -
第十二章 PL/SQL应用程序性能调优
2008-04-24 10:27 1728第十二章 PL/SQL应用程序性能调优 一、PL/SQL ... -
第十一章 本地动态SQL
2008-04-24 10:26 2093第十一章 本地动态SQL ... -
第十章 PL/SQL对象类型 ( 2 )
2008-04-24 10:24 1461七、声明并初始化对象 ... -
第十章 PL/SQL对象类型 ( 1 )
2008-04-24 10:20 3280第十章 PL/SQL对象类型 一、抽象的角色 抽象是对一个 ... -
第九章 PL/SQL包
2008-04-24 10:17 1912一、什么是PL/SQL包 包就是一个把各种逻辑相关的类型、常量 ... -
第八章 PL/SQL子程序
2008-04-24 10:16 1431一、什么是子程序 子程 ... -
第七章 控制PL/SQL错误
2008-04-24 10:14 2077一、错误控制一览 在PL/SQL中,警告或错误被称为异常。异 ... -
第六章 PL/SQL与Oracle间交互(3)
2008-04-24 10:13 157412、游标变量的限制 目前,游标变量有以下限制: 不能在包 ... -
第六章 PL/SQL与Oracle间交互(2)
2008-04-24 10:11 1416四、使用游标FOR循环 在 ... -
第六章 PL/SQL与Oracle间交互 ( 1 )
2008-04-24 10:05 1768第六章 PL/SQL与Oracle间 ... -
第五章 PL/SQL集合与记录(4)
2008-04-24 10:03 1357十四、利用BULK COLLECTION子句为集合赋值 关键字 ... -
第五章 PL/SQL集合与记录(2)
2008-04-24 09:59 1621八、在SQL语句中使用PL/S ... -
第五章 PL/SQL集合与记录(1)
2008-04-24 09:53 1867第五章 PL/SQL集合与记 ... -
第二章 PL/SQL基础(2)
2008-04-24 09:49 1282四、PL/SQL命名规范 同样 ... -
第二章 PL/SQL基础(1)
2008-04-24 09:48 2825第二章 PL/SQL基础 一、字符集 在PL/SQL程 ... -
第四章 PL/SQL的控制结构
2008-04-24 09:39 1451第四章 PL/SQL的控制结 ... -
第三章 PL/SQL数据类型
2008-04-24 08:38 3120第三章 PL/SQL数据类型 ... -
第一章 PL/SQL一览
2008-04-24 08:34 1691第一章 PL/SQL一览 一、理解PL/SQL的主要特性 ...
相关推荐
第五章 PL-SQL集合与记录(1) 第六章 PL-SQL集合与记录(2) 第七章 PL-SQL与Oracle间交互 第八章 控制PL-SQL错误 第九章 PL-SQL子程序 第十章 PL-SQL包 第十一章 PL-SQL对象类型 第十二章 本地动态SQL 第十三章 PL...
第5部分 构造PL/SQL应用程序 第17章 过程、函数与参数 543 第18章 包 593 第19章 触发器 626 第20章 管理PL/SQL代码 685 第21章 PL/SQL的性能优化 753 第22章 I/O操作和PL/SQL 843 第6部分 高级PL/SQL主题 第23章 ...
《oracle pl/sql程序设计(第5版)》基于oracle数据库11g,从pl/sql编程、pl/sql程序结构、pl/sql程序数据、pl/sql中的sql、pl/sql应用构建、高级pl/sql主题6个方面详细系统地讨论了pl/sql以及如何有效地使用它。...
- **集合与记录**:学习如何使用PL/SQL中的集合和记录类型,这些结构可以帮助更高效地处理数据集。 - **游标**:介绍游标的使用方法,包括隐式游标和显式游标,以及如何利用游标遍历查询结果。 #### 四、PL/SQL中的...
第5章 sql和pl/sql综述 第6章 简单查询 第7章 sql单行函数 第8章 操纵数据 第9章 复杂查询 第10章 管理常用对象 第三部分 pl/sql 第11章 pl/sql基础 第12章 访问oracle 第13章 编写控制结构 第...
第5章 sql和pl/sql综述 第6章 简单查询 第7章 sql单行函数 第8章 操纵数据 第9章 复杂查询 第10章 管理常用对象 第三部分 pl/sql 第11章 pl/sql基础 第12章 访问oracle 第13章 编写控制结构 第...
《ORACLE PL/SQL程序设计第五版》是深入学习Oracle数据库编程的重要参考资料,它涵盖了PL/SQL语言的基础到高级概念,旨在帮助读者迅速提升在Oracle环境中编写高效、可靠的存储过程和函数的能力。这本书分为上、下两...
第5部分 构造PL/SQL应用程序 第17章 过程、函数与参数 543 第18章 包 593 第19章 触发器 626 第20章 管理PL/SQL代码 685 第21章 PL/SQL的性能优化 753 第22章 I/O操作和PL/SQL 843 第6部分 高级PL/SQL主题 第23章 ...
《ORACLE PL/SQL 程序设计(第五版)》是Oracle数据库开发领域的一本经典教程,专注于讲解如何使用PL/SQL这一强大的过程化语言进行数据库编程。这本书旨在帮助读者掌握PL/SQL的基本概念、语法和高级特性,以便在实际...
PL/SQL提供了多种类型的集合来满足不同的编程需求,主要包括数组(Arrays)、记录(Records)、表(Tables)以及对象(Objects)。本文将重点介绍数组、记录、表和对象的使用方法及相关函数。 #### 二、数组...
第5章SQL和PL/SQL综述 第6章简单查询 第7章SQL单行函数 第8章操纵数据 第9章复杂查询 第10章管理常用对象 第三部分PL/SQL 第11章PL/SQL基础 第12章访问Oracle 第13章编写控制结构 第14章使用...
这是Steven Feuerstein的经典著作《Oracle PL/SQL Programming》的第五版,被誉为PL/SQL编程的权威指南。书中不仅讲解了基本概念,还包括了许多高级主题,如并发控制、事务管理、错误处理策略、性能调优技巧,以及PL...
#### 第五章 PL/SQL集合与记录 - **集合**: - **TABLE**:有序集合,支持重复元素。 - **VARRAY**:变长数组,长度固定但元素可变。 - **记录**: - 定义记录类型,存储不同类型的值。 #### 第六章 PL/SQL与...
- Bulk Collect允许高效地将数据库结果集批量收集到PL/SQL集合中,提高性能。 12. **与SQL的交互** - PL/SQL可以直接执行DML(INSERT、UPDATE、DELETE)和DDL(CREATE、ALTER、DROP)语句,也可以使用动态SQL执行...
利用PL/SQL调试器或第三方工具进行调试,找出程序错误。 通过遵循这些Oracle PL/SQL的最佳实践,您可以构建高效、稳定且易于维护的数据库应用程序。持续学习和实践,不断提升自己的技能,是成为优秀Oracle PL/SQL...
### 第一章 PL/SQL程序设计简介 PL/SQL(Procedural Language/Structured Query Language)结合了SQL的查询功能和一种类似C或Pascal的编程语法,使得开发人员能够在数据库环境中编写存储过程、函数、触发器等。PL/...
### Oracle PL/SQL 语言袖珍参考手册第五版 (2015) 知识点概览 #### 核心内容概述 《Oracle PL/SQL 语言袖珍参考手册》(第五版)由三位专家Steven Feuerstein、Bill Pribyl和Chip Dawes共同编著,是一本专为Oracle...
PL/SQL 是 Oracle 数据库的一种过程化语言,用于编写数据库应用程序。它结合了 SQL 查询功能和高级编程元素,如变量、流程控制结构和异常处理。本文主要总结了 PL/SQL 的一些基本语句和操作,特别关注在 ORACLE 报表...