本文纯属个人见解,是对前面学习的总结,如有描述不正确的地方还请高手指正~
第四章 控制结构(也较比基本,就只做例子了)
--MEMBER OF的用使 23:14:07 SCOTT@orcl> DECLARE 23:14:09 2 TYPE LIST IS TABLE OF VARCHAR2(10); 23:14:09 3 N VARCHAR2(10) := 'One'; 23:14:09 4 A LIST := LIST('One', 'Two', 'Three'); 23:14:09 5 BEGIN 23:14:09 6 IF N MEMBER OF A THEN 23:14:09 7 DBMS_OUTPUT.PUT_LINE('"n" is member.'); 23:14:09 8 END IF; 23:14:09 9 END; 23:14:11 10 / "n" is member. PL/SQL 进程已胜利成完。
--SUBMULTISET的用使 23:14:13 SCOTT@orcl> DECLARE 23:15:33 2 TYPE LIST IS TABLE OF INTEGER; 23:15:33 3 A LIST := LIST(1, 2, 3); 23:15:33 4 B LIST := LIST(1, 2, 3, 4); 23:15:33 5 BEGIN 23:15:33 6 IF A SUBMULTISET B THEN 23:15:33 7 DBMS_OUTPUT.PUT_LINE('Subset.'); 23:15:33 8 END IF; 23:15:33 9 END; 23:15:34 10 / Subset. PL/SQL 进程已胜利成完。
1.IF语句
格式:
IF [NOT] {comparison_expression | boolean_value} [[AND | OR]
{comparison_expression | boolean_value}] THEN
true_execution_block;
[ELSE
false_execution_block;]
END IF;
23:19:29 SCOTT@orcl> DECLARE 23:19:35 2 ONE_THING VARCHAR2(5) := 'Three'; 23:19:35 3 FUNCTION ORDINAL(N NUMBER) RETURN VARCHAR2 IS 23:19:35 4 TYPE ORDINAL_TYPE IS TABLE OF VARCHAR2(5); 23:19:35 5 ORDINAL ORDINAL_TYPE := ORDINAL_TYPE('One', 'Two', 'Three', 'our'); 23:19:35 6 BEGIN 23:19:35 7 RETURN ORDINAL(N); 23:19:35 8 END; 23:19:35 9 BEGIN 23:19:35 10 IF ONE_THING = ORDINAL(3) THEN 23:19:35 11 DBMS_OUTPUT.PUT_LINE('[' || ORDINAL(3) || ']'); 23:19:35 12 END IF; 23:19:35 13 END; 23:19:36 14 / [Three] PL/SQL 进程已胜利成完。
2.CASE语句
CASE [ TRUE | [selector_variable]]
WHEN [criterion1 | expression1] THEN
criterion1_statements;
WHEN [criterion2 | expression2] THEN
criterion2_statements;
WHEN [criterion(n+1) | expression(n+1)] THEN
criterion(n+1)_statements;
ELSE
block_statements;
END CASE;
3.迭代语句
23:24:02 SCOTT@orcl> DECLARE 23:24:04 2 COUNTER NUMBER; 23:24:04 3 FIRST BOOLEAN; 23:24:04 4 BEGIN 23:24:04 5 LOOP 23:24:04 6 -- Loop index management. 23:24:04 7 IF NVL(COUNTER, 1) >= 1 THEN 23:24:04 8 IF NOT NVL(FIRST, TRUE) THEN 23:24:04 9 COUNTER := COUNTER + 1; 23:24:04 10 ELSE 23:24:04 11 COUNTER := 1; 23:24:04 12 FIRST := FALSE; 23:24:04 13 END IF; 23:24:04 14 END IF; 23:24:04 15 -- Exit management. 23:24:04 16 EXIT WHEN NOT COUNTER < 3; 23:24:04 17 DBMS_OUTPUT.PUT_LINE('Iteration [' || COUNTER || ']'); 23:24:04 18 END LOOP; 23:24:04 19 END; 23:24:04 20 / Iteration [1] Iteration [2] PL/SQL 进程已胜利成完。
23:24:05 hr@orcl> DECLARE 23:26:06 2 COUNTER NUMBER; 23:26:06 3 FIRST BOOLEAN; 23:26:06 4 BEGIN 23:26:06 5 LOOP 23:26:06 6 -- Loop index management. 23:26:06 7 IF NVL(COUNTER, 1) >= 1 THEN 23:26:06 8 IF NOT NVL(FIRST, TRUE) THEN 23:26:06 9 COUNTER := COUNTER + 1; 23:26:06 10 ELSE 23:26:06 11 COUNTER := 1; 23:26:06 12 FIRST := FALSE; 23:26:06 13 END IF; 23:26:06 14 END IF; 23:26:06 15 DBMS_OUTPUT.PUT_LINE('Iteration [' || COUNTER || ']'); 23:26:06 16 -- Exit management. 23:26:06 17 EXIT WHEN NOT COUNTER < 3; 23:26:06 18 END LOOP; 23:26:06 19 END; 23:26:07 20 / Iteration [1] Iteration [2] Iteration [3] PL/SQL 进程已胜利成完。
--CONTINUE的用使 23:35:55 hr@orcl> DECLARE 23:35:57 2 COUNTER NUMBER; 23:35:57 3 FIRST BOOLEAN; 23:35:57 4 BEGIN 23:35:57 5 LOOP 23:35:57 6 -- Loop index management. 23:35:57 7 IF NVL(COUNTER, 1) >= 1 THEN 23:35:57 8 IF NOT NVL(FIRST, TRUE) THEN 23:35:57 9 COUNTER := COUNTER + 1; 23:35:57 10 ELSE 23:35:57 11 COUNTER := 1; 23:35:57 12 FIRST := FALSE; 23:35:57 13 END IF; 23:35:57 14 END IF; 23:35:57 15 -- Exit management. 23:35:57 16 EXIT WHEN NOT COUNTER < 3; 23:35:57 17 IF COUNTER = 2 THEN 23:35:57 18 CONTINUE; 23:35:57 19 ELSE 23:35:57 20 DBMS_OUTPUT.PUT_LINE('Index [' || COUNTER || '].'); 23:35:57 21 END IF; 23:35:57 22 END LOOP; 23:35:57 23 END; 23:35:57 24 / Index [1]. PL/SQL 进程已胜利成完。
4.FOR环循语句
格式:
FOR range_index IN range_bottom..range_top LOOP
repeating_statements;
END LOOP;
23:35:59 hr@orcl> BEGIN 23:38:44 2 FOR i IN 1..3 LOOP 23:38:44 3 dbms_output.put_line('Iteration ['||i||']'); 23:38:44 4 END LOOP; 23:38:44 5 END; 23:38:46 6 / Iteration [1] Iteration [2] Iteration [3] PL/SQL 进程已胜利成完。
--标游FOR环循
BEGIN
FOR I IN (SELECT COUNT(*) AS ON_HAND, ITEM_TITLE, ITEM_RATING
FROM ITEM
WHERE ITEM_TITLE LIKE 'Harry Potter%'
AND ITEM_RATING_AGENCY = 'MPAA'
GROUP BY ITEM_TITLE, ITEM_RATING) LOOP
DBMS_OUTPUT.PUT('(' || I.ON_HAND || ') ');
DBMS_OUTPUT.PUT(I.ITEM_TITLE || ' ');
DBMS_OUTPUT.PUT_LINE('[' || I.ITEM_RATING || ']');
END LOOP;
END;
5.WHILE环循语句
格式:
WHILE entry_condition LOOP
[counter_management_statements;]
repeating_statements;
END LOOP;
例:
23:38:47 hr@orcl> DECLARE 23:40:35 2 COUNTER NUMBER := 1; 23:40:35 3 BEGIN 23:40:35 4 WHILE (COUNTER < 3) LOOP 23:40:35 5 DBMS_OUTPUT.PUT_LINE('Index [' || COUNTER || '].'); 23:40:35 6 IF COUNTER >= 1 THEN 23:40:35 7 COUNTER := COUNTER + 1; 23:40:35 8 END IF; 23:40:35 9 END LOOP; 23:40:35 10 END; 23:40:35 11 / Index [1]. Index [2]. PL/SQL 进程已胜利成完。
--goto的用使 23:40:36 hr@orcl> DECLARE 23:41:34 2 COUNTER NUMBER := 1; 23:41:34 3 BEGIN 23:41:34 4 WHILE (COUNTER < 3) LOOP 23:41:34 5 IF COUNTER = 2 THEN 23:41:34 6 GOTO LOOPINDEX; 23:41:34 7 ELSE 23:41:34 8 DBMS_OUTPUT.PUT_LINE('Index [' || COUNTER || '].'); 23:41:34 9 END IF; 23:41:34 10 <<LOOPINDEX>> 23:41:34 11 IF COUNTER >= 1 THEN 23:41:34 12 COUNTER := COUNTER + 1; 23:41:34 13 END IF; 23:41:34 14 END LOOP; 23:41:34 15 END; 23:41:35 16 / Index [1]. PL/SQL 进程已胜利成完。
6.标游结构
隐式标游
--隐式标游的%ROWCOUN性属 23:41:35 hr@orcl> DECLARE 23:43:06 2 N NUMBER; 23:43:06 3 BEGIN 23:43:06 4 SELECT 1 INTO N FROM DUAL;--单行隐式标游 23:43:06 5 DBMS_OUTPUT.PUT_LINE('Selected [' || SQL%ROWCOUNT || ']'); 23:43:06 6 END; 23:43:06 7 / Selected [1] PL/SQL 进程已胜利成完。
--记载型类的用使
DECLARE
TYPE ITEM_RECORD IS RECORD(
ID ITEM.ITEM_ID%TYPE,
TITLE ITEM.ITEM_TITLE%TYPE,
SUBTITLE ITEM.ITEM_SUBTITLE%TYPE);
DATASET ITEM_RECORD;
BEGIN
SELECT ITEM_ID, ITEM_TITLE, ITEM_SUBTITLE
INTO DATASET
FROM ITEM
WHERE ROWNUM < 2;
DBMS_OUTPUT.PUT_LINE('Selected [' || DATASET.TITLE || ']');
END;
--多行隐式标游
BEGIN
UPDATE SYSTEM_USER SET LAST_UPDATE_DATE = SYSDATE;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('Updated [' || SQL%ROWCOUNT || ']');
ELSE
DBMS_OUTPUT.PUT_LINE('Nothing updated!');
END IF;
END;
--多行隐式标游
BEGIN
FOR I IN (SELECT ITEM_ID, ITEM_TITLE FROM ITEM) LOOP--种这隐式标游的SQL%ROWCOUNT性属将回返NULL
DBMS_OUTPUT.PUT_LINE('Item #[' || I.ITEM_ID || '][' || I.ITEM_TITLE || ']');
END LOOP;
END;
示显标游
静态示显标游
DECLARE
ID ITEM.ITEM_ID%TYPE;
TITLE VARCHAR2(60);
CURSOR C IS
SELECT ITEM_ID, ITEM_TITLE FROM ITEM;
BEGIN
OPEN C;
LOOP
FETCH C
INTO ID, TITLE;
EXIT WHEN C%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Title [' || TITLE || ']');
END LOOP;
CLOSE C;
END;
等价于=>
DECLARE
CURSOR C IS
SELECT ITEM_ID AS ID, ITEM_TITLE AS TITLE FROM ITEM;
BEGIN
FOR I IN C LOOP
DBMS_OUTPUT.PUT_LINE('Title [' || I.TITLE || ']');
END LOOP;
END;
--示显标游中用使记载型类
DECLARE
TYPE ITEM_RECORD IS RECORD(
ID NUMBER,
TITLE VARCHAR2(60));
ITEM ITEM_RECORD;
CURSOR C IS
SELECT ITEM_ID, ITEM_TITLE FROM ITEM;
BEGIN
OPEN C;
LOOP
FETCH C
INTO ITEM;
EXIT WHEN C%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Title [' || ITEM.TITLE || ']');
END LOOP;
END;
等价于=>
DECLARE
TYPE ITEM_RECORD IS RECORD(
ID NUMBER,
TITLE VARCHAR2(60));
EXPLICIT_ITEM ITEM_RECORD;
CURSOR C IS
SELECT ITEM_ID AS ID, ITEM_TITLE AS TITLE FROM ITEM;
BEGIN
FOR I IN C LOOP
EXPLICIT_ITEM := I;
DBMS_OUTPUT.PUT_LINE('Title [' || EXPLICIT_ITEM.TITLE || ']');
END LOOP;
END;
--有条件的退出环循,种这示显标游没法用FOR环循改写
DECLARE
TYPE ITEM_RECORD IS RECORD(
ID NUMBER,
TITLE VARCHAR2(60));
ITEM ITEM_RECORD;
CURSOR C IS
SELECT ITEM_ID, ITEM_TITLE FROM ITEM WHERE ITEM_ID = -1;
BEGIN
OPEN C;
LOOP
FETCH C
INTO ITEM;
IF C%NOTFOUND THEN
IF C%ROWCOUNT = 0 THEN
DBMS_OUTPUT.PUT_LINE('No Data Found');
END IF;
EXIT;
ELSE
DBMS_OUTPUT.PUT_LINE('Title [' || ITEM.TITLE || ']');
END IF;
END LOOP;
END;
动态示显标游
DECLARE
LOWEND NUMBER;
HIGHEND NUMBER;
ITEM_ID NUMBER := 1012;
TYPE ITEM_RECORD IS RECORD(
ID NUMBER,
TITLE VARCHAR2(60));
ITEM ITEM_RECORD;
CURSOR C(LOW_ID NUMBER, HIGH_ID NUMBER) IS--带参标游
SELECT ITEM_ID, ITEM_TITLE
FROM ITEM
WHERE ITEM_ID BETWEEN LOW_ID AND HIGH_ID;
BEGIN
LOWEND := TO_NUMBER(NVL(&1, 1005));
HIGHEND := TO_NUMBER(NVL(&2, 1021));
OPEN C(LOWEND, HIGHEND);
LOOP
FETCH C
INTO ITEM;
EXIT WHEN C%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Title [' || ITEM.TITLE || ']');
END LOOP;
END;
用使部份改写为FOR环循为:
FOR i IN c (lowend,highend) LOOP
item := i;
dbms_output.put_line('Title ['||item.title||']');
END LOOP;
7.BULK语句
BULK语句让你从表或视图查询、入插、更新、删除大据数集.
它有2个标游性属:
%BULK_ROWCOUNT(I):查看元素是不是被改更
%BULK_EXCEPTION(I):查看某行是不是到遇错误
格式:
SELECT column1 [, column2 [, column(n+1)]]
COLLECT BULK INTO collection1 [, collection2 [, collection(n+1)]]
FROM table_name
[WHERE where_clause_statements];
FETCH cursor_name [(parameter1 [, parameter2 [, parameter(n+1)]])]
BULK COLLECT INTO collection1 [, collection2 [, collection(n+1)]]
[LIMIT rows_to_return];
--隐式BULK标游,SELECT BULK是行并执行的
DECLARE
TYPE TITLE_COLLECTION IS TABLE OF VARCHAR2(60);
TYPE SUBTITLE_COLLECTION IS TABLE OF VARCHAR2(60);
TITLE TITLE_COLLECTION;
SUBTITLE SUBTITLE_COLLECTION;
BEGIN
SELECT ITEM_TITLE, ITEM_SUBTITLE BULK COLLECT
INTO TITLE, SUBTITLE
FROM ITEM;
-- Print one element of one of the parallel collections.
FOR I IN 1 .. TITLE.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Title [' || TITLE(I) || ']');
END LOOP;
END;
--BULK中用使记载量变
DECLARE
TYPE TITLE_RECORD IS RECORD(
TITLE VARCHAR2(60),
SUBTITLE VARCHAR2(60));
TYPE COLLECTION IS TABLE OF TITLE_RECORD;
FULL_TITLE COLLECTION;
BEGIN
SELECT ITEM_TITLE, ITEM_SUBTITLE BULK COLLECT INTO FULL_TITLE FROM ITEM;
-- Print one element of a structure.
FOR I IN 1 .. FULL_TITLE.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Title [' || FULL_TITLE(I).TITLE || ']');
END LOOP;
END;
--行并行数制约
DECLARE
-- Define scalar datatypes.
TYPE TITLE_COLLECTION IS TABLE OF VARCHAR2(60);
TYPE SUBTITLE_COLLECTION IS TABLE OF VARCHAR2(60);
-- Define local variables.
TITLE TITLE_COLLECTION;
SUBTITLE SUBTITLE_COLLECTION;
-- Define a static cursor.
CURSOR C IS
SELECT ITEM_TITLE, ITEM_SUBTITLE FROM ITEM;
BEGIN
OPEN C;
LOOP
FETCH C BULK COLLECT
INTO TITLE, SUBTITLE LIMIT 10;--制约每10个一次
EXIT WHEN TITLE.COUNT = 0;
FOR I IN 1 .. TITLE.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Title [' || TITLE(I) || ']');
END LOOP;
END LOOP;
END;
8. FORALL语句
FORALL语句计划用来理处集合型类的.
--用使FORALL行进批量入插
DECLARE
TYPE ID_COLLECTION IS TABLE OF NUMBER;
TYPE TITLE_COLLECTION IS TABLE OF VARCHAR2(60);
TYPE SUBTITLE_COLLECTION IS TABLE OF VARCHAR2(60);
ID ID_COLLECTION;
TITLE TITLE_COLLECTION;
SUBTITLE SUBTITLE_COLLECTION;
CURSOR C IS
SELECT ITEM_ID, ITEM_TITLE, ITEM_SUBTITLE FROM ITEM;
BEGIN
OPEN C;
LOOP
FETCH C BULK COLLECT
INTO ID, TITLE, SUBTITLE LIMIT 10;
EXIT WHEN TITLE.COUNT = 0;
FORALL I IN ID.FIRST .. ID.LAST --FORALL的用使
INSERT INTO ITEM_TEMP VALUES (ID(I), TITLE(I), SUBTITLE(I));
END LOOP;
FOR I IN ID.FIRST .. ID.LAST LOOP
DBMS_OUTPUT.PUT('Inserted [' || ID(I) || ']');
DBMS_OUTPUT.PUT_LINE('[' || SQL%BULK_ROWCOUNT(I) || ']');
END LOOP;
END;
--用使FORALL行进批量更新
DECLARE
TYPE ID_COLLECTION IS TABLE OF NUMBER;
TYPE TITLE_COLLECTION IS TABLE OF VARCHAR2(60);
ID ID_COLLECTION;
TITLE TITLE_COLLECTION;
CURSOR C IS
SELECT ITEM_ID, ITEM_TITLE FROM ITEM;
BEGIN
OPEN C;
LOOP
FETCH C BULK COLLECT
INTO ID, TITLE LIMIT 10;
EXIT WHEN TITLE.COUNT = 0;
FORALL I IN ID.FIRST .. ID.LAST
UPDATE ITEM_TEMP SET TITLE = TITLE(I) || ': ' WHERE ID = ID(I);
END LOOP;
END;
--用使FORALL行进批量删除
DECLARE
TYPE ID_COLLECTION IS TABLE OF NUMBER;
TYPE TITLE_COLLECTION IS TABLE OF VARCHAR2(60);
ID ID_COLLECTION;
TITLE TITLE_COLLECTION;
CURSOR C IS
SELECT ITEM_ID, ITEM_TITLE FROM ITEM;
BEGIN
OPEN C;
LOOP
FETCH C BULK COLLECT
INTO ID, TITLE LIMIT 10;
EXIT WHEN TITLE.COUNT = 0;
FORALL I IN ID.FIRST .. ID.LAST
DELETE FROM ITEM_TEMP
WHERE SUBTITLE IS NULL
AND ID = ID(I);
END LOOP;
END;
第5章 错误管理(Error Management)
异常型类和异常理处范围
有两种型类的错误:译编错误和运行时错误.译编错误在语法析解的时候就会发明,运行时错误是当现实据数在程序中按
定预规矩理处的时候产生的错误.
运行时错误一般会都在以后块被异常理处捕捉到(声明块的异常没法被以后异常理处块捕捉),译编错误(如声明处量变定义错误)以后块没法捕捉.
译编错误
译编错误很罕见,如果你输错关键字,记忘分号,记忘括号等等,会都激发译编错误.
如:
--少分号的 22:11:57 hr@orcl> BEGIN 22:12:19 2 dbms_output.put_line('Hello World.') 22:12:19 3 END; 22:12:21 4 / END; * 第 3 行现出错误: ORA-06550: 第 3 行, 第 1 列: PLS-00103: 现出符号 "END"在须要列下之一时: := . ( % ; 符号 ";" 被替换为 "END" 后继承。 --未定义型类长度 22:12:22 hr@orcl> DECLARE 22:13:51 2 A CHAR := 'AB';--未定义型类长度 22:13:51 3 BEGIN 22:13:51 4 DBMS_OUTPUT.PUT_LINE('[' || A || ']'); 22:13:51 5 END; 22:13:52 6 / DECLARE * 第 1 行现出错误: ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 ORA-06512: 在 line 2
综上可以看出译编错误,给出的错误提示一般是不确准的,须要自己去断判.
运行时错误
运行时错误可以产生在声明块、执行块、异常块.声明块及异常块产生的运行时错误只有外部异常块才能捕捉.
异常块格式:
WHEN {predefined_exception | user_defined_exception | OTHERS} THEN
exception_handling_statement;
[RETURN | EXIT ];
异常块理处的异常分为系统定预义异常、用户自定义异常及其他异常.
系统定预义异常定义在SYS.STANDARD包里,异常块里用常SQLCODE和SQLERRM两个函数出输错误信息.
系统定预义异常对照表
SQLCODE出输一个oracle定预义的正数,此正数对应oracle系统一系列定预义异常.
意注:有一个异常是破例的NO_DATA_FOUND异常回返的SQLCODE是100.
SQLERRM回返错误信息及定义的错误代码.
例:
--系统定预义异常VALUE_ERROR 22:25:51 hr@orcl> DECLARE 22:25:59 2 A VARCHAR2(1); 22:25:59 3 B VARCHAR2(2) := 'AB'; 22:25:59 4 BEGIN 22:25:59 5 A := B;--这里产生运行时错误 22:25:59 6 EXCEPTION 22:25:59 7 WHEN VALUE_ERROR THEN 22:25:59 8 DBMS_OUTPUT.PUT_LINE('You can''t put [' || B ||'] in a one character string.'); 22:25:59 10 END; 22:25:59 11 / You can't put [AB] in a one character string. PL/SQL 进程已胜利成完。 --用WHEN OHTERS捕捉系统定预义异常NO_DATA_FOUND 22:26:00 hr@orcl> DECLARE 22:28:44 2 A NUMBER; 22:28:44 3 BEGIN 22:28:44 4 DECLARE 22:28:44 5 B VARCHAR2(2); 22:28:44 6 BEGIN 22:28:44 7 SELECT 1 INTO B FROM DUAL WHERE 1 = 2;--此处产生运行时错误 22:28:44 8 A := B; 22:28:44 9 EXCEPTION--里层异常理处 22:28:44 10 WHEN VALUE_ERROR THEN 22:28:44 11 DBMS_OUTPUT.PUT_LINE('You can''t put [' || B || 22:28:44 12 '] in a one character string.'); 22:28:44 13 END; 22:28:44 14 EXCEPTION--外层异常理处 22:28:44 15 WHEN OTHERS THEN 22:28:44 16 DBMS_OUTPUT.PUT_LINE('Caught in outer block [' || SQLERRM || '].'); 22:28:44 17 END; 22:28:46 18 / Caught in outer block [ORA-01403: 未找到任何据数]. PL/SQL 进程已胜利成完。
--用户自定义异常 22:28:47 hr@orcl> DECLARE 22:31:24 2 A NUMBER; 22:31:24 3 E EXCEPTION; 22:31:24 4 BEGIN 22:31:24 5 DECLARE 22:31:24 6 B VARCHAR2(2) := 'AB'; 22:31:24 7 BEGIN 22:31:24 8 RAISE E;--自动抛出异常,意注此异常量变是在外层定义的,所以只能被外层捕捉 22:31:24 9 EXCEPTION 22:31:24 10 WHEN OTHERS THEN 22:31:24 11 A := B; 22:31:24 12 DBMS_OUTPUT.PUT_LINE('Does not reach this line.'); 22:31:24 13 END; 22:31:24 14 EXCEPTION 22:31:24 15 WHEN OTHERS THEN --此处捕捉异常 22:31:24 16 DBMS_OUTPUT.PUT_LINE('Caught in outer block [' || SQLCODE || '].'); 22:31:24 17 END; 22:31:25 18 / Caught in outer block [-6502]. PL/SQL 进程已胜利成完。
--声明处的运行时错误,以后的异常块是没法捕捉以后声明块的运行时错误的 22:34:33 hr@orcl> DECLARE 22:34:35 2 A VARCHAR2(1) := 'a1'; 22:34:35 3 BEGIN 22:34:35 4 DBMS_OUTPUT.PUT_LINE('Substituted variable value [' || A || ']'); 22:34:35 5 EXCEPTION 22:34:35 6 WHEN OTHERS THEN 22:34:35 7 DBMS_OUTPUT.PUT_LINE('Local exception caught.'); 22:34:35 8 END; 22:34:35 9 / DECLARE * 第 1 行现出错误: ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 ORA-06512: 在 line 2
--外部异常块捕捉声明处运行时错误 22:36:42 hr@orcl> BEGIN 22:37:21 2 DECLARE 22:37:21 3 A VARCHAR2(1) := 'a1';--部内声明块产生运行时错误 22:37:21 4 BEGIN 22:37:21 5 DBMS_OUTPUT.PUT_LINE('Substituted variable value [' || A || ']'); 22:37:21 6 EXCEPTION 22:37:21 7 WHEN OTHERS THEN 22:37:21 8 DBMS_OUTPUT.PUT_LINE('Local exception caught.'); 22:37:21 9 END; 22:37:21 10 EXCEPTION 22:37:21 11 WHEN OTHERS THEN--外部异常块捕捉到 22:37:21 12 DBMS_OUTPUT.PUT_LINE('Outer exception caught.'); 22:37:21 13 END; 22:37:21 14 / Outer exception caught. PL/SQL 进程已胜利成完。
--函数中的声明块异常理处 --注:不议建在声明处用使动态值赋 22:41:39 hr@orcl> CREATE OR REPLACE FUNCTION RUNTIME_ERROR(VARIABLE_IN VARCHAR2) 22:41:43 2 RETURN VARCHAR2 IS 22:41:43 3 A VARCHAR2(1) := VARIABLE_IN; 22:41:43 4 BEGIN 22:41:43 5 RETURN NULL; 22:41:43 6 EXCEPTION 22:41:43 7 WHEN OTHERS THEN 22:41:43 8 DBMS_OUTPUT.PUT_LINE('Function error.'); 22:41:43 9 END; 22:41:44 10 / 函数已建创。 --产生声明处错误,异常理处块未捕捉到 22:41:45 hr@orcl> SELECT runtime_error ('AB') FROM dual; SELECT runtime_error ('AB') FROM dual * 第 1 行现出错误: ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 ORA-06512: 在 "GW.RUNTIME_ERROR", line 3
用户自定义异常
两种型类的用户自定义异常:
1.在声明处声明EXCEPTION型类的量变;
2.用使函数RAISE_APPLICATION_ERROR在执行块动态立建异常(用使的异常号范围为-20000到-20999)
例:
--第一类用户自定义异常 22:57:37 hr@orcl> DECLARE 22:57:41 2 E EXCEPTION; 22:57:41 3 BEGIN 22:57:41 4 RAISE E; 22:57:41 5 DBMS_OUTPUT.PUT_LINE('Can''t get here.'); 22:57:41 6 EXCEPTION 22:57:41 7 WHEN OTHERS THEN 22:57:41 8 IF SQLCODE = 1 THEN--全部用户自定义异常的SQLCODE都为1 22:57:41 9 DBMS_OUTPUT.PUT_LINE('This is a [' || SQLERRM || '].'); 22:57:41 10 END IF; 22:57:41 11 END; 22:57:41 12 / This is a [User-Defined Exception]. PL/SQL 进程已胜利成完。 --第一类用户自定义异常,绑定了系统的定预义错误号-2003 22:57:42 hr@orcl> DECLARE 22:59:54 2 A VARCHAR2(20); 22:59:54 3 INVALID_USERENV_PARAMETER EXCEPTION; 22:59:54 4 PRAGMA EXCEPTION_INIT(INVALID_USERENV_PARAMETER, -2003); 22:59:54 5 BEGIN 22:59:54 6 A := SYS_CONTEXT('USERENV', 'PROXY_PUSHER'); 22:59:54 7 EXCEPTION 22:59:54 8 WHEN INVALID_USERENV_PARAMETER THEN 22:59:54 9 DBMS_OUTPUT.PUT_LINE(SQLERRM); 22:59:54 10 END; 22:59:55 11 / ORA-02003: 无效的 USERENV 数参 PL/SQL 进程已胜利成完。 --第二类用户自定义异常 22:59:56 hr@orcl> BEGIN 23:01:34 2 RAISE_APPLICATION_ERROR(-20001, 'A not too original message.'); 23:01:34 3 EXCEPTION 23:01:34 4 WHEN OTHERS THEN 23:01:34 5 DBMS_OUTPUT.PUT_LINE(SQLERRM); 23:01:34 6 END; 23:01:35 7 / ORA-20001: A not too original message. PL/SQL 进程已胜利成完。 --一、二类用户自定义异常合结用使 23:01:35 hr@orcl> DECLARE 23:03:20 2 E EXCEPTION;--定义异常量变 23:03:20 3 PRAGMA EXCEPTION_INIT(E, -20001);--绑定错误号-20001 23:03:20 4 BEGIN 23:03:20 5 RAISE_APPLICATION_ERROR(-20001, 'A less than original message.');--抛出异常 23:03:20 6 EXCEPTION 23:03:20 7 WHEN E THEN--捕捉异常,-20001和E经已绑定 23:03:20 8 DBMS_OUTPUT.PUT_LINE(SQLERRM); 23:03:20 9 END; 23:03:20 10 / ORA-20001: A less than original message. PL/SQL 进程已胜利成完。
文章结束给大家分享下程序员的一些笑话语录: 一边用着越狱的ip,一边拜乔帮主的果粉自以为是果粉,其实在乔帮主的眼里是不折不扣的叛徒。