• 异常、错误oracle 11g PL/SQL Programming学习三by小雨


    本文纯属个人见解,是对前面学习的总结,如有描述不正确的地方还请高手指正~

        第四章  控制结构(也较比基本,就只做例子了)

    --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,一边拜乔帮主的果粉自以为是果粉,其实在乔帮主的眼里是不折不扣的叛徒。

  • 相关阅读:
    thinkPHP 远程数据库和远程连接数据库表名大小写混合
    浏览器兼容性的问题
    input 的那些事
    jquery ui draggable失效的问题
    thinkphp在php5.6以上版本显示"No input file specified"
    ajax dataType
    DOM对象的处理
    ubuntu 16.4 中eth0添加ip地址,且可以上网
    linux 安装phpstudy
    select样式清除
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3028530.html
Copyright © 2020-2023  润新知