- 浏览: 1762993 次
- 性别:
- 来自: 成都
文章分类
- 全部博客 (520)
- Oracle (10)
- Oracle错误集 (8)
- Oracle安装升级 (15)
- Oracle日常管理 (51)
- Oracle字符集 (7)
- Oracle备份恢复 (24)
- Oracle优化 (4)
- Oracle编程 (52)
- Oracle导入导出 (19)
- Oracle体系结构 (15)
- Oracle网络 (2)
- Oracle安全 (2)
- Oracle权限 (3)
- Oracle数据字典和性能视图 (2)
- Oracle常用地址 (5)
- SQLPLUS专栏 (7)
- SqlServer (13)
- SqlServer2005编程 (27)
- SqlServer2005管理 (15)
- MySQL (20)
- Dorado应用 (1)
- C# (24)
- Arcgis Server开发 (20)
- ArcSDE技术 (19)
- UML学习 (2)
- 设计模式 (2)
- JAVA EE (4)
- JavaScript (3)
- OFBIZ (27)
- JAVA WEB开发 (22)
- Linux&Unix (34)
- SHELL编程 (14)
- C语言 (11)
- 网络协议 (14)
- FREEMARKER (2)
- GROOVY (2)
- JAVA语言 (3)
- 防火墙 (0)
- PHP (2)
- Apache (2)
- Loader Runner (1)
- Nginx (3)
- 数据库理论 (2)
- maven (1)
最新评论
-
怼怼怼怼:
oracle的timestamp类型使用 -
怼怼怼怼:
oracle的timestamp类型使用 -
怼怼怼怼:
oracle的timestamp类型使用 -
pg_guo:
感谢
oracle中查看用户权限 -
xu234234:
5、MapResourceManager控件中添加了两个服务, ...
北京ArcGis Server应用基础培训笔记1
一、PL/SQL控制结构一览
根据结构定理(structure theorem),任何计算机程序都可以用下图中的基本控制结构来表示。它们可以任意组合来解决问题。
选择结构是用于测试条件的,根据条件的真假,执行一系列语句。一个条件语句可以是任何能够返回布尔值(TRUE或FALSE)的变量或表达式。循环结构能在条件满足的情况下反复执行。序列结构只是简单的按照顺序执行语句。
二、条件控制:IF和CASE语句
有时候,我们需要根据具体的条件来采取不同的对策。IF语句就能让我们按条件来执行语句序列。也就是说,语句序列的执行与否取决于某个给定的条件。有三种IF语句:IF-THEN、IF-THEN-ELSE和IF-THEN-ELSIF。CASE语句是条件判断的精简形式,它能计算条件表达式的值并在多个对应动作中做出选择。
1、IF-THEN语句
IF语句最简单的形式就是把一个条件和一个语句序列用关键字THEN和END IF关联起来:
IF condition THEN
sequence_of_statements
END IF;
只有在条件值为真的时候语句序列才能被执行。如果条件值为假或是空,IF语句就什么都不做。无论哪种情况,控制权最后还是会被传递到下一个语句,如下例:
IF sales > QUOTA THEN
compute_bonus(empid);
UPDATE payroll
SET pay = pay + bonus
WHERE empno = emp_id;
END IF;
如果我们把IF语句放到一行,就可以像下面这样编写:
IF x > y THEN high := x; END IF;
2、IF-THEN-ELSE语句
第二种形式的IF语句使用关键字ELSE添加了一个额外的处理选项,如下:
IF condition THEN
sequence_of_statements1
ELSE
sequence_of_statements2
END IF;
当条件为假或空时,ELSE子句中的语句序列就会被执行。下例中,第一个UPDATE语句在条件为真的情况下执行,而第二个UPDATE语句在条件为假或为空的情况下才会被执行:
IF trans_type = 'CR' THEN
UPDATE accounts
SET balance = balance + credit
WHERE ...
ELSE
UPDATE accounts
SET balance = balance - debit
WHERE ...
END IF;
THEN和ELSE子句中也可以包含IF语句。就是说IF语句能够被嵌套使用,如下例所示:
IF trans_type = 'CR' THEN
UPDATE accounts
SET balance = balance + credit
WHERE ...
ELSE
IF new_balance >= minimum_balance THEN
UPDATE accounts
SET balance = balance - debit
WHERE ...
ELSE
RAISE insufficient_funds;
END IF;
END IF;
3、IF-THEN-ELSIF语句
有时我们可能需要从几个选项中选择一个,这时我们就需要使用第三种IF语句,添加一个ELSIF关键字提供额外的条件选项,使用方法如下:
IF condition1 THEN
sequence_of_statements1
ELSIF condition2 THEN
sequence_of_statements2
ELSE
sequence_of_statements3
END IF;
如果第一个条件为假或空,ELSIF子句就会检测另外一个条件。一个IF语句可以有多个ELSIF子句;最后一个ELSE子句是可选的。条件表达式从上而下的计算。只要有满足的条件,与它关联的语句就会执行,然后控制权转到下一个语句。如果所有的条件都为假或是空,ELSE部分的语句就会执行。看一下下面的例子:
BEGIN
...
IF sales > 50000 THEN
bonus := 1500;
ELSIF sales > 35000 THEN
bonus := 500;
ELSE
bonus := 100;
END IF;
INSERT INTO payroll
VALUES (emp_id, bonus, ...);
END;
如果sales的值大于50000的话,第一个和第二个条件就为真。然而,bonus只会被赋予1500的值,因为第二个条件并没有执行到。当第一个条件为真的话,它关联的语句就会执行,然后控制权转到INSERT语句。
4、CASE语句
同IF语句一样,CASE语句也是选出一个语句序列来执行。但是,为了选择出合适的语句序列,CASE会使用一个选择器,而不是多个布尔表达式。想要比较IF和CASE语句的话,请看下面对学校成绩的描述信息:
IF grade = 'A' THEN
DBMS_OUTPUT.put_line('Excellent');
ELSIF grade = 'B' THEN
DBMS_OUTPUT.put_line('Very Good');
ELSIF grade = 'C' THEN
DBMS_OUTPUT.put_line('Good');
ELSIF grade = 'D' THEN
DBMS_OUTPUT.put_line('Fair');
ELSIF grade = 'F' THEN
DBMS_OUTPUT.put_line('Poor');
ELSE
DBMS_OUTPUT.put_line('No such grade');
END IF;
请注意这五个布尔表达式,在每一个实例中,我们只对同一变量的值进行检测,看它的分数值是否等于"A"、"B"、"C"、"D"、"E"或"F"。下面我们用CASE语句重新编写上面的程序:
CASE grade
WHEN 'A' THEN
DBMS_OUTPUT.put_line('Excellent');
WHEN 'B' THEN
DBMS_OUTPUT.put_line('Very Good');
WHEN 'C' THEN
DBMS_OUTPUT.put_line('Good');
WHEN 'D' THEN
DBMS_OUTPUT.put_line('Fair');
WHEN 'F' THEN
DBMS_OUTPUT.put_line('Poor');
ELSE
DBMS_OUTPUT.put_line('No such grade');
END CASE;
CASE语句的可读性高而且高效,所以,如果可能的话,尽量把IF-THEN-ELEIF都改写成CASE语句。
CASE语句以关键字CASE开头,然后跟上一个选择器,也就是上例中的变量grade。选择器表达式可能是很复杂的。例如,它有可能是一个函数调用。但在通常情况下,它只是一个独立的变量。选择器表达式只被计算一次。它的值可以是除BLOB、BFILE、对象类型、PL/SQL记录、索引表、变长数组或嵌套表之外的任何有效的PL/SQL数据类型。
选择器后面跟着一个或多个WHEN子句,它们是按顺序检测的。选择器的值决定了哪个子句被执行。如果选择器的值等于WHEN子句的表达式值, WHEN子句中的语句序列就会被执行。例如在上面例子中,如果grade等于"C",程序就会输出"Good"。当WHEN子句中的语句序列被执行完毕,控制权会转到下一个语句,而不会再执行后续的WHEN子句。
ELSE子句的工作原理与IF中的类似。上例子中,如果grade的值不与任何一个WHEN子句匹配,ELSE部分就会被执行,"No such grade"就会被输出。ELSE子语是可选的。但是,如果我们省略了ELSE子句,PL/SQL就会为我们添加隐式的ELSE子句:
ELSE RAISE CASE_NOT_FOUND;
如果CASE语句选择了隐式的ELSE子句,PL/SQL就会抛出预定义异常CASE_NOT_FOUND。所以,即使我们省略了ELSE子句,ELSE也会有一个默认的动作。
关键字END CASE是CASE语句结束的标志。这两个关键字必须用空格分开。形式如下:
[<<label_name>>]
CASE selector
WHEN expression1 THEN
sequence_of_statements1;
WHEN expression2 THEN
sequence_of_statements2;
...
WHEN expressionn THEN
sequence_of_statementsn;
[ELSE sequence_of_statementsN+1;]
END CASE [label_name];
同PL/SQL块一样,CASE语句也是可以加标签的。标签是一个未声明的标识符,必须出现在CASE语句的开头,用双尖括号夹起来。标签的名称也可以出现在CASE语句的结尾处,但不是必须的。
CASE语句中的异常会按正常的方法处理,就是说正常的执行语句停止,控制权转到PL/SQL块或子程序的异常控制部分。
- 搜寻式CASE语句
PL/SQL还提供下面搜寻形式的CASE语句:
[<<label_name>>]
CASE
WHEN search_condition1 THEN
sequence_of_statements1;
WHEN search_condition2 THEN
sequence_of_statements2;
...
WHEN search_conditionn THEN
sequence_of_statementsn;
[ELSE sequence_of_statementsN+1;]
END CASE [label_name];
搜寻式CASE语句没有选择器。并且,它的WHEN子句只能包含结果为布尔类型的表达式,产生其它类型结果的表达式是不允许的。示例如下:
CASE
WHEN grade = 'A' THEN
DBMS_OUTPUT.put_line('Excellent');
WHEN grade = 'B' THEN
DBMS_OUTPUT.put_line('Very Good');
WHEN grade = 'C' THEN
DBMS_OUTPUT.put_line('Good');
WHEN grade = 'D' THEN
DBMS_OUTPUT.put_line('Fair');
WHEN grade = 'F' THEN
DBMS_OUTPUT.put_line('Poor');
ELSE
DBMS_OUTPUT.put_line('No such grade');
END CASE;
搜寻条件是按顺序计算的。每个搜寻条件的布尔值决定了哪个WHEN子句被执行。一旦WHEN子句被执行,控制权就会被交给下一个语句,后续的搜寻条件就不会被考虑。
如果没有找到搜寻条件为TRUE的子句,ELSE子句就会执行。ELSE虽然是可选的,但是,如果省略了ELSE,PL/SQL就会添加隐式的ELSE子句:
ELSE RAISE CASE_NOT_FOUND;
如果执行过程中有异常发生,我们可以在块或子程序的异常控制部分捕获到。
5、PL/SQL条件控制语句使用准则
我们不应该像下面这样使用笨拙的IF语句:
IF new_balance < minimum_balance THEN
overdrawn := TRUE;
ELSE
overdrawn := FALSE;
END IF;
...
IF overdrawn = TRUE THEN
RAISE insufficient_funds;
END IF;
上面的代码忽视了两个地方。首先,布尔表达式的值可以直接赋给布尔变量。所以我们可以把第一个IF语句简化成下面的语句形式:
overdrawn := new_balance < minimum_balance;
第二,布尔变量本身就是TRUE或FALSE。所以,在IF的条件表达式中直接使用变量本身即可:
IF overdrawn THEN ...
尽可能地使用ELSIF子句代替嵌套IF语句。这样我们的代码就更易读易理解。比较下面两个IF语句:
IF condition1 THEN
statement1;
ELSE
IF condition2 THEN
statement2;
ELSE
IF condition3 THEN
statement3;
END IF;
END IF;
END IF;IF condition1 THEN
statement1;
ELSIF condition2 THEN
statement2;
ELSIF condition3 THEN
statement3;
END IF;
这两个语句在逻辑上是等价的,但第一个语句看起来有些混乱,而第二个就较为明显。
如果把单独一个表达式与多个值进行比较的话,我们可以使用CASE语句来代替多个ELSIF子句。
三、循环控制:LOOP和EXIT语句
LOOP语句能让我们反复执行一个语句序列。有三种形式的LOOP语句:LOOP,WHILE-LOOP和FOR-LOOP。
1、LOOP
LOOP语句最简单的形式就是把语句序列放到关键字LOOP和END LOOP之间,语法如下:
LOOP
sequence_of_statements;
END LOOP;
在每一个循环中,语句序列都会被顺序执行,然后再返回循环顶部从头执行。如果不想继续执行,可以使用EXIT语句退出循环。我们可以把一个或多个EXIT语句放到循环里,但不能放到循环外面。有两种形式的EXIT语句:EXIT和EXIT-WHEN。
- EXIT
EXIT语句会强迫循环无条件终止。当遇到EXIT语句时,循环会立即终止,并把控制权交给下面的语句。示例如下:
LOOP
...
IF credit_rating < 3 THEN
...
EXIT; -- exit loop immediately
END IF;
END LOOP;
-- control resumes here
下面再举一个不能在PL/SQL块中使用EXIT语句的例子:
BEGIN
...
IF credit_rating < 3 THEN
...
EXIT; -- not allowed
END IF;
END;
记住,EXIT语句必须放在循环内。如果想在PL/SQL块正常到达程序结尾之前而终止执行,可以使用RETURN语句。
- EXIT-WHEN
EXIT-WHEN语句可以根据给定的条件跳出循环。当遇到EXIT语句时,WHEN子句中的表达式值就会被计算。如果条件满足,循环就会被终止,控制权转到循环语句之后的语句。示例如下:
LOOP
FETCH c1
INTO ...
EXIT WHEN c1%NOTFOUND; -- exit loop if condition is true
...
END LOOP;
CLOSE c1;
在条件满足之前,循环是不会结束的。所以,循环里的语句必须要改变循环条件的值。上例中,如果FETCH语句返回了一行值,WNEN子句中的条件就为假;如果不能返回结果,WNEN子句中的条件就为真,循环就会结束,控制权转入CLOSE语句。
EXIT-WHEN语句可以替代简单的IF语句,例如,比较下面两段代码:
IF count > 100 THEN
EXIT;
END IF;EXIT WHEN count > 100;
这两个语句在逻辑上是等价的,但EXIT-WHEN语句更容易阅读和理解。
- 循环标签
跟PL/SQL块一样,循环也是可以添加标签。标签必须出现在LOOP语句的开端,语法如下:
<<label_name>>
LOOP
sequence_of_statements
END LOOP;
而在LOOP语句结束部分出现的标签名称是可选的,语法如下:
<<my_loop>>
LOOP
...
END LOOP my_loop;
在LOOP结束部分使用标签名称能够改善可读性。
无论使用哪种EXIT语句形式,都可以结束一个封闭的LOOP块,而不仅仅局限于当前的LOOP块。只要在我们想结束的封闭LOOP块上添加一个标签,然后像下面这样在EXIT语句中使用这个标签就可以了:
<<outer>>
LOOP
...
LOOP
...
EXIT outer WHEN ... -- exit both loops
END LOOP;
...
END LOOP outer;
2、WHILE-LOOP
WHILE-LOOP语句用关键字LOOP和END LOOP把语句序列封闭起来并与一个布尔条件表达式相关联:
WHILE condition LOOP
sequence_of_statements
END LOOP;
每次循环之前,程序都是计算布尔表达式的值。如果条件为真,语句序列就会被执行,然后重新返回循环顶部计算布尔表达式的值;如果布尔表达式的值为假或空,控制权就会被交给循环之后的语句。下面看一个例子:
WHILE total <= 25000 LOOP
...
SELECT sal
INTO salary
FROM emp
WHERE x = x; ...
total := total + salary;
END LOOP;
循环的次数是与条件相关的,而且在循环结束之前是未知的。由于条件是在循环顶部测试的,所以语句序列有可能一次都没有执行。在上面的例子中,如果total的初始值比25000大,那么条件值就是假,循环就会被跳过。
有些语言有LOOP UNTIL或是REPEAT UNTIL这样的结构,在底部测试条件表达式的值。这样,语句序列就会至少执行一次。PL/SQL没有这样的结构,但我们可以变通地使用下面的方法来实现这样的功能:
LOOP
sequence_of_statements
EXIT WHEN boolean_expression;
END LOOP;
要保证WHILE循环至少执行一次,在条件表达式中使用初始化过的布尔变量,如下例所示:
done := FALSE;
WHILE NOT done LOOP
sequence_of_statements;
done := boolean_expression;
END LOOP;
在循环内的语句必须为布尔变量赋上一个新值。否则循环就会无限地执行下去。如下例的两个LOOP语句在逻辑上是等价的:
WHILE TRUE LOOP
...
END LOOP;LOOP
...
END LOOP;
3、FOR-LOOP
FOR语句会在指定的整数范围内进行循环操作。循环的内容被关键字FOR和LOOP封闭起来。两个"点"(..)作为范围操作符来使用。语法如下:
FOR counter IN [REVERSE] lower_bound..higher_bound LOOP
sequence_of_statements
END LOOP;
当首次进入FOR循环时,循环的范围就会被确定下来,并且不会重新计算。如下例所示,语句序列会执行三次,每执行一次,循环因子就会增加1。
FOR i IN 1 .. 3 LOOP -- assign the values 1,2,3 to i
sequence_of_statements -- executes three times
END LOOP;
下例演示了如果下界值等于上界值,循环中的语句序列只执行一次:
FOR i IN 3 .. 3 LOOP -- assign the values 3 to i
sequence_of_statements -- executes one time
END LOOP;
默认情况下,循环总是从下界到上界。不过也可以使用REVERSE关键字,让循环从上界往下界执行。但是要记住,范围的书写格式仍旧是递增顺序的。
FOR i IN REVERSE 1 .. 3 LOOP -- assign the values 3,2,1 to i
sequence_of_statements -- executes three times
END LOOP;
FOR循环里,循环计数器只能当作常量来引用且不能为它赋值,如下例:
FOR ctr IN 1 .. 10 LOOP
IF NOT finished THEN
INSERT INTO ...
VALUES (ctr); -- legal
factor := ctr * 2; -- legal
ELSE
ctr := 10; -- not allowed
END IF;
END LOOP;
- 迭代法
循环范围的边界可以是文字、变量或表达式,但它们都必须是数字。否则PL/SQL会抛出预定义异常VALUE_ERROR。如下例,下界不一定非得是1。但循环计数器只能是每次增加1。
j IN -5 .. 5
k IN REVERSE first..last
step IN 0..TRUNC(high/low) * 2
在PL/SQL内部,它会把边界值赋给一个临时的PLS_INTEGER变量,并在需要的时候把值转换成最接近的整数。PLS_INTEGER的范围是-2**31到2**31之间。所以,如果边界值超过这个范围,我们就会得到一个数字溢出错误:
DECLARE
hi NUMBER := 2 ** 32;
BEGIN
FOR j IN 1 .. hi LOOP -- causes a 鈥檔umeric overflow鈥?error
...
END LOOP;
END;
有些语言提供了STEP子句,它能让我们指定循环增量。PL/SQL没有这样的结构,但我们可以在FOR循环内扩大循环计数器的倍数来实现这样的功能。在下面的例子中,我们今天的日期赋给索引表的第一个、第五个和第十五个元素。
DECLARE
TYPE datelist IS TABLE OF DATE
INDEX BY BINARY_INTEGER;
dates datelist;
k CONSTANT INTEGER := 5; -- set new increment
BEGIN
FOR j IN 1 .. 3 LOOP
dates(j * k) := SYSDATE; -- multiply loop counter by increment
END LOOP;
...
END;
- 动态范围
PL/SQL允许我们在运行时决定循环的范围,如下例所示:
SELECT COUNT(empno)
INTO emp_count
FROM emp;
FOR i IN 1 .. emp_count LOOP
...
END LOOP;
emp_count在运行时是未知的;SELECT语句在运行时才返回结果值。
如果循环范围中的下界值超过上界值会怎样呢?如下例所示,循环内的语句序列就不会被执行,控制权直接交给下一个语句:
-- limit becomes 1
FOR i IN 2 .. LIMIT LOOP
sequence_of_statements -- executes zero times
END LOOP;
-- control passes here
- 作用域规则
循环计数器只在循环内部定义,我们不能在循环外引用它。循环退出后,循环计数器就会失效,如下例:
FOR ctr IN 1 .. 10 LOOP
...
END LOOP;
sum := ctr - 1; -- not allowed
我们不需要显式声明循环计数器,因为它会被隐式地声明为INTEGER类型本地变量。下面的例子中本地声明覆盖了全局声明:
DECLARE
ctr INTEGER;
BEGIN
...
FOR ctr IN 1 .. 25 LOOP
...
IF ctr > 10 THEN ... -- refers to loop counter
END LOOP;
END;
如果想在上例中引用全局变量,我们就得借助标签和点标志,例如:
<<main>>
DECLARE
ctr INTEGER;
...
BEGIN
...
FOR ctr IN 1 .. 25 LOOP
...
IF main.ctr > 10 THEN -- refers to global variable
...
END IF;
END LOOP;
END main;
同样的作用域规则也适用于嵌套FOR循环。如下面的例子,两个循环计数器的名字相同,所以,用从内层循环引用外层循环的循环计数器,就必须使用标签和点标志:
<<outer>>
FOR step IN 1 .. 25 LOOP
FOR step IN 1 .. 10 LOOP
...
IF outer.step > 15 THEN ...
END LOOP;
END LOOP outer;
- 使用EXIT语句
EXIT语句可以立即结束一个FOR循环。例如,下面的循环语句正常情况应该执行十次,但是,如果FETCH语句取得数据失败,循环就会立即终止,无论它执行过多少次:
FOR j IN 1 .. 10 LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
...
END LOOP;
在使用EXIT时,我们可以结束任何封闭循环,而不仅仅是当前循环。只要在我们想结束的封闭循环上加上标签,然后在EXIT语句中引用它,就能结束做过标记的FOR循环了,如下例:
<<outer>>
FOR i IN 1 .. 5 LOOP
...
FOR j IN 1 .. 10 LOOP
FETCH c1 INTO emp_rec;
EXIT outer WHEN c1%NOTFOUND; -- exit both FOR loops
...
END LOOP;
END LOOP outer;
-- control passes here
四、顺序控制:GOTO和NULL语句
与IF和LOOP语句不通,GOTO和NULL语句对PL/SQL编程来说不是必须的。PL/SQL结构中很少用到GOTO语句。有时,它就是用于简化逻辑的。NULL用于改善可读性使条件语句看起来更加清晰。
滥用GOTO能使结构混乱,不易理解和维护(有时被称为意大利面条式代码 - spaghetti code)。所以,GOTO语句的使用一定要有节制。例如,要从一个深嵌套中跳到异常控制块,要用异常抛出而不是使用GOTO语句。
1、GOTO语句
GOTO语句可以无条件跳到一个标签处。标签名称在它所处的作用范围内必须是唯一的。执行的时候,GOTO语句会把控制权交给一个做了标记的语句或块。GOTO语句可以向上或向下跳转,示例如下:
BEGIN
...
GOTO insert_row;
...
<<insert_row>>
INSERT INTO emp VALUES ...
END;
再看一个向上跳转的例子:
BEGIN
...
<<update_row>>
BEGIN
UPDATE emp SET ...
...
END;
...
GOTO update_row;
...
END;
下例中的标签end_loop是不允许的,因为它并没有到达一个处理语句:
DECLARE
done BOOLEAN;
BEGIN
...
FOR i IN 1 .. 50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<<end_loop>> -- not allowed
END LOOP; -- not an executable statement
END;
改进方法很简单,只需添加一个NULL语句即可:
FOR i IN 1 .. 50 LOOP
IF done THEN
GOTO end_loop;
END IF;
...
<<end_loop>>
NULL; -- an executable statement
END LOOP;
GOTO语句还能从当前块跳入一个封闭的块中:
DECLARE
my_ename CHAR(10);
BEGIN
<<get_name>>
SELECT ename
INTO my_ename
FROM emp
WHERE ...
BEGIN
...
GOTO get_name; -- branch to enclosing block
END;
END;
- 约束
有些情况下,GOTO语句是不能使用的。特别是想用GOTO语句跳到IF、CASE、LOOP或子块。例如,下面的GOTO语句是不允许的:
BEGIN
...
GOTO update_row; -- can’t branch into IF statement
...
IF valid THEN
...
<<update_row>>
UPDATE emp SET ...
END IF;
END;
如下例所示,GOTO不能从一个IF的一个分支跳到另一个分支。同样,也不能从CASE的一个WHEN子句跳到另一个WHEN子句。
BEGIN
...
IF valid THEN
...
GOTO update_row; -- can’t branch into ELSE clause
ELSE
...
<<update_row>>
UPDATE emp SET ...
END IF;
END;
下例中演示了GOTO语句不能从封闭的块跳入它的子块:
BEGIN
...
IF status = 'OBSOLETE' THEN
GOTO delete_part; -- can’t branch into sub-block
END IF;
...
BEGIN
...
<<delete_part>>
DELETE FROM parts WHERE ...
END;
END;
同样,GOTO也不能跳出子程序:
DECLARE
...
PROCEDURE compute_bonus(emp_id NUMBER) IS
BEGIN
...
GOTO update_row; -- can’t branch out of subprogram
END;
BEGIN
...
<<update_row>>
UPDATE emp SET ...
END;
最后,GOTO不能从异常控制部分跳入当前块。例如,下面的GOTO语句就是不允许的:
DECLARE
...
pe_ratio REAL;
BEGIN
...
SELECT price / NVL(earnings, 0)
INTO pe_ratio
FROM ...
<<insert_row>>
INSERT INTO stats
VALUES (pe_ratio, ...);
EXCEPTION
WHEN ZERO_DIVIDE THEN
pe_ratio := 0;
GOTO insert_row; -- can't branch into current block
END;
但是,GOTO语句可以从一个异常控制程序中跳转到一个封闭块。
2、NULL语句
NULL语句本身什么都不做,只是简单的把控制权交给下一个语句而已。在控制结构中,NULL只是告诉阅读者一个可能会被考虑到的情况,而实际的没有任何动作。下面的例子中演示了忽视未命名异常的操作:
EXCEPTION
WHEN ZERO_DIVIDE THEN
ROLLBACK;
WHEN VALUE_ERROR THEN
INSERT INTO errors VALUES ...
COMMIT;
WHEN OTHERS THEN
NULL;
在IF语句中或其他一些需要至少有一个可执行语句的地方,NULL语句就会被使用来满足这种语法。下例中,NULL语句强调了只有顶级(top-rated)雇员才能得到红利:
IF rating > 90 THEN
compute_bonus(emp_id);
ELSE
NULL;
END IF;
在程序设计时,NULL语句很容易创建stub程序。stub程序是一段虚设的子程序,它能让我们推迟函数或过程的实现。因为子程序的可执行部分至少需要一句可执行语句,NULL语句就会派上用场,充当占位语句,如下例:
PROCEDURE debit_account(acct_id INTEGER, amount REAL) IS
BEGIN
NULL;
END debit_account;
发表评论
-
To_Date函数用法
2014-11-07 11:04 1721spl> select * from emp ... -
Oracle中的MD5加密
2014-02-15 10:18 1465一、技术点 1、 DBMS_OBFUSCATION_TO ... -
oracle行列转换总结
2014-02-15 10:18 1006最近论坛很多人提的问题都与行列转换有关系,所以我对行列转换 ... -
Oracle数据库中的''与NULL的关系
2014-02-15 10:17 1321在Oracle数据库中''与NULL是等价的。均表示空值, ... -
快速删除重复的记录
2014-02-15 10:17 647做项目的时候,一位同事导数据的时候,不小心把一个表中的数据 ... -
Oracle的rownum原理和使用
2014-02-15 10:17 1114Oracle的rownum原理和使用 在Oracle中, ... -
ORACLE中查询某个字段包含回车换行符
2013-04-11 15:42 11286很简单,但是很多人一下估计还不一定知道。 select * ... -
ORACLE触发器(转)
2013-03-06 23:58 1157本篇主要内容如下: ... -
使用forall语句的bulk dml操作
2008-11-13 17:27 3793在oracle 8i或更高版本的forall语句中,oracl ... -
判断俩个值的大小函数sign
2008-11-10 11:13 2935比较大小select decode(sign(变量1-变量2) ... -
Oracle 触发器应用
2008-11-06 15:37 2203触发器是特定事件出现的时候,自动执行的代码块。类似于存储过程, ... -
PLSQL学习笔记
2008-10-23 16:58 2284在网上看到的一个比较好的PLSQL学习笔记,放在这里方便以后查 ... -
Oracle自定义函数实例
2008-10-22 16:35 20098--没有参数的函数 create or replace fun ... -
Oracle自定义类型使用一例
2008-10-22 16:28 4281一、创建自定义类型 create type t_air as ... -
Oracle存储过程实例
2008-10-22 15:30 3522/*不带任何参数存储过程*/ create or replac ... -
Oracle的异常处理
2008-10-22 14:40 3034oracle提供了预定义例外 ... -
识别低效的语句
2008-10-15 09:04 1465SELECT EXECUTIONS , DISK_READS, ... -
wmsys.wm_concat、sys_connect_by_path、自定义函数实现行列转换
2008-10-08 16:35 4473构建测试表: create table TABLE1 ( ... -
PL/SQL Developer使用技巧
2008-10-07 15:18 67191、PL/SQL Developer记住登陆密码 在使用 ... -
Oracle 绑定变量
2008-10-06 10:53 4382在oracle 中,对于一个提交的sql语句,存在两种可选的解 ...
相关推荐
第4部分 PL/SQL中的SQL 第14章 DML和事务管理 423 第15章 数据提取 444 第16章 动态SQL和动态PL/SQL 492 目 录(下册) 第5部分 构造PL/SQL应用程序 第17章 过程、函数与参数 543 第18章 包 593 第19章 触发器 626 第...
标题中的“pl/sql developer11.0”指的是该软件的第11个主要版本。在本文中,我们将深入探讨PL/SQL Developer的功能、特性以及它在Oracle数据库开发中的作用。 PL/SQL(Procedural Language/Structured Query ...
第4章 使用sql*plus 第二部分 sql 第5章 sql和pl/sql综述 第6章 简单查询 第7章 sql单行函数 第8章 操纵数据 第9章 复杂查询 第10章 管理常用对象 第三部分 pl/sql 第11章 pl/sql基础 第12章 访问...
《oracle pl/sql程序设计(第5版)》基于oracle数据库11g,从pl/sql编程、pl/sql程序结构、pl/sql程序数据、pl/sql中的sql、pl/sql应用构建、高级pl/sql主题6个方面详细系统地讨论了pl/sql以及如何有效地使用它。...
第4章 使用sql*plus 第二部分 sql 第5章 sql和pl/sql综述 第6章 简单查询 第7章 sql单行函数 第8章 操纵数据 第9章 复杂查询 第10章 管理常用对象 第三部分 pl/sql 第11章 pl/sql基础 第12章 访问...
第四章 PL-SQL的控制结构 第五章 PL-SQL集合与记录(1) 第六章 PL-SQL集合与记录(2) 第七章 PL-SQL与Oracle间交互 第八章 控制PL-SQL错误 第九章 PL-SQL子程序 第十章 PL-SQL包 第十一章 PL-SQL对象类型 第十二章...
#### 四、PL/SQL中的SQL - **SQL语句的执行**:介绍如何在PL/SQL代码中嵌入SQL语句,包括查询、插入、更新和删除操作。 - **动态SQL**:探讨如何构造和执行动态SQL语句,这对于需要根据运行时条件生成SQL的情况非常...
控制结构(第4~7章) 异常处理(第8~10章) 游标(第11~12章) 触发器(第13~14章) 复合数据类型(第15~16章) 动态SQL(第17章) 批量SQL(第18章) 子程序和包(第19~22章) Oracle中对象类型(第23章) Oracle...
第三章“控制结构”深入讲解了PL/SQL中的流程控制语句,如IF-THEN-ELSE、CASE、WHILE循环、FOR循环等,这些都是编写逻辑复杂程序的基础。 第四章“使用复合数据类型”会涵盖Oracle中的多种数据类型,如数组、记录和...
第4部分 PL/SQL中的SQL 第14章 DML和事务管理 423 第15章 数据提取 444 第16章 动态SQL和动态PL/SQL 492 目 录(下册) 第5部分 构造PL/SQL应用程序 第17章 过程、函数与参数 543 第18章 包 593 第19章 触发器 626 第...
它结合了SQL的数据处理能力和传统编程语言的控制结构,使开发者能够在数据库环境中编写复杂的应用程序。PL/SQL直接在数据库服务器内部执行,这使得数据处理速度更快,同时也降低了网络通信的开销。 #### 二、PL/SQL...
PL/SQL是Oracle数据库中的一个核心组件,全称为Procedural Language/Structured Query Language,即过程化结构化查询语言。它是SQL的扩展,允许开发者在SQL的基础上添加过程化编程元素,如循环、条件判断和子程序等...
第4章使用SQL*Plus 第二部分SQL 第5章SQL和PL/SQL综述 第6章简单查询 第7章SQL单行函数 第8章操纵数据 第9章复杂查询 第10章管理常用对象 第三部分PL/SQL 第11章PL/SQL基础 第12章访问Oracle 第...
第四章 PL/SQL控制结构是Oracle数据库中的编程基础,它涉及到如何通过编程逻辑来控制PL/SQL块的执行流程。PL/SQL,全称为Procedural Language/Structured Query Language,是Oracle数据库支持的一种过程化语言,它...
条件分支语句是 PL/SQL 中的一种控制结构,用于根据条件执行不同的语句。条件分支语句可以是简单的,也可以是复杂的,例如使用 IF 语句、CASE 语句等。 十八、循环语句 循环语句是 PL/SQL 中的一种控制结构,用于...
- **第4章**:异常处理机制的深入探讨。 2. **进阶章节** - **第5章**:事务管理的深入讲解。 - **第6章**:触发器的设计与实现。 - **第7章**:面向对象编程的基础知识。 - **第8章**:存储过程与函数的创建与...
PL/SQL,全称Procedural Language/Structured Query Language,是Oracle数据库的一种扩展,它集成了SQL语言的查询功能和过程性编程语言的控制结构,为数据库开发提供了强大的工具。这个"PL/SQL中文帮助手册"是7.0...
《ORACLE PL/SQL 程序设计(第五版)》是Oracle数据库开发领域的一本经典教程,专注于讲解如何使用PL/SQL这一强大的过程化语言进行数据库编程。这本书旨在帮助读者掌握PL/SQL的基本概念、语法和高级特性,以便在实际...
"PLSQL.zip_oracl_oracle pl/sql ppt_pl sql ppt tutorial_pl/sql plsql.ppt"这个压缩包提供了学习PL/SQL的基础材料,通过"第一章 pl-sql介绍.ppt"开始你的学习之旅,逐步探索这个强大而灵活的数据库编程语言。