• PL/SQL基本程序结构和语句(三)


    目录

    1.PL/SQL的程序框架

    2.条件结构

    (1)IF-THEN语句

    (2)IF-THEN-ELSE语句

    (3)IF-THEN-ELSIF-THEN-ELSE语句

    3.循环体结构

    (1)LOOP-EXIT-END语句

    (2)LOOP-EXIT-WHEN-END循环

    (3)WHILE-LOOP-END循环 

    (4)FOR-IN-LOOP-END循环

    4.选择和跳转语句

    (1)CASE语句

    (2)GOTO语句

    5.异常处理

    (1)预定义异常

    (2)用户自定义异常


    PL/SQL基础知识点(一)

    PL/SQL变量,常量和数据类型(二)

    1.PL/SQL的程序框架

    1. [DELCARE]
    2. --声明部分
    3. BEGIN
    4. --执行部分
    5. [EXCEPTION]
    6. --异常处理部分
    7. END

    2.条件结构

    (1)IF-THEN语句

    IF<表达式>THEN

           

    END IF;

    例子:

    已建好的表XSB(学生表)

    根据上面的表进行操作:

    --现在要求输出XSB表中的分数SCORE大于50的学生人数:

    --设置输出缓冲
    SET SERVEROUTPUT ON;
    DECLARE 
        v_num NUMBER(3);
    BEGIN
        SELECT COUNT(*) INTO v_num
            FROM XSB
            WHERE score>50;
        IF v_num!=0 THEN
            DBMS_OUTPUT.PUT_LINE('总学法>50: '||TO_CHAR(v_num));
        END IF;
    END;

    (2)IF-THEN-ELSE语句

     IF<表达式>THEN

           

    ELSE

           

    END IF;

    例子:还是使用上面学生表

    求学生的平均学分是否大于50

    SET SERVEROUTPUT ON;
    DECLARE
        v_avg number(4,2);
    BEGIN
        SELECT AVG(score) INTO v_avg
            FROM XSB;
        IF v_avg>50 THEN
            dbms_output.put_line('平均学分大于50');
        ELSE
            dbms_output.put_line('平均学分小于50');
        END IF;
    END; 

    (3)IF-THEN-ELSIF-THEN-ELSE语句

     IF<表达式1>THEN

           

    ELSIF<表达式2>THEN

           

    ELSE

           

    END IF;

    例子:求x^+4x+3=0

    SET SERVEROUTPUT ON;
    declare
        a number;
        b number;
        c number;
        x1 number;
        x2 number;
        d number;
    BEGIN 
        a:=1;
        b:=4;
        c:=3;
        d:=b*b-4*a*c;
        IF a=0 THEN
            x1:=-c/b;
            DBMS_OUTPUT.PUT_LINE('只有一个平方根: '||to_char(x1));
        ELSIF d<0 THEN
            DBMS_OUTPUT.PUT_LINE('没有算术平方根');
        ELSE
            x1:=(-b+sqrt(d))/(2*a);
            x2:=(-b-sqrt(d))/(2*a);
            DBMS_OUTPUT.PUT_LINE('x1 = '||to_char(x1));
            DBMS_OUTPUT.PUT_LINE('x2 = '||to_char(x2));
        END IF;
    END;
     

    3.循环体结构

    (1)LOOP-EXIT-END语句

    LOOP

            <循环体>

            IF <条件表达式>THEN

                    EXIT;

            END IF;

    END LOOP

     --求10的阶乘
    SET SERVEROUTPUT ON;
    DECLARE
        fact number:=1;
        cnt number:=2;
    BEGIN
        LOOP
            fact:=fact*cnt;
            cnt:=cnt+1;
            IF cnt>10 THEN
                EXIT;
            END IF;
        END LOOP;
        DBMS_OUTPUT.PUT_LINE('10! = '||to_char(fact));
    END;

    (2)LOOP-EXIT-WHEN-END循环

     LOOP

            <循环体>

            EXIT WHEN<条件表达式>

    END LOOP;

    例子:求10的阶乘。 

    SET SERVEROUTPUT ON;
    DECLARE 
        n number:=1;
        cnt number:=2;
    BEGIN
        LOOP
            n:=n*cnt;
            cnt:=cnt+1;
            EXIT WHEN cnt=11;
        END LOOP;
        DBMS_OUTPUT.PUT_LINE('10! = '||TO_CHAR(n));
    END;
     

    (3)WHILE-LOOP-END循环 

    WHILE<条件表达式>

            LOOP

                    <循环体>

            END LOOP;

    例子:求10的阶乘。 

     SET SERVEROUTPUT ON;
    DECLARE 
        n number:=1;
        cnt number:=2;
    BEGIN
        WHILE cnt<=10
        LOOP
            n:=n*cnt;
            cnt:=cnt+1;
        END LOOP;
        DBMS_OUTPUT.PUT_LINE('10! = '||TO_CHAR(n));
    END;

    (4)FOR-IN-LOOP-END循环

    FOR<循环变量名> IN <变量初始值>..<变量终值>

            LOOP

                    <循环体>

            END LOOP;

    例子:求10的阶乘。 

    SET SERVEROUTPUT ON;
    DECLARE 
        n number:=1;
        cnt number:=2;
    BEGIN
        FOR cnt IN 2..10
            LOOP
                n:=n*cnt;
            END LOOP;
        DBMS_OUTPUT.PUT_LINE('10! = '||TO_CHAR(n));
    END;
     

    4.选择和跳转语句

    (1)CASE语句

    CASE <变量名>

            WHEN <值1> THEN <语句1>

            WHEN <值2> THEN <语句2>

            ...

            WHEN <值n> THEN <语句n>

    END CASE;

    例子:根据上面创建的表,通过学生号查找学生的专业。

    SET SERVEROUTPUT ON;
    DECLARE 
        v_key xsb.sid%TYPE;
        v_result varchar2(20);
    BEGIN 
        SELECT sid INTO v_key
            FROM XSB
            WHERE sname='王林';
        CASE v_key
            WHEN '151101' THEN v_result:='计算机专业';
            WHEN '151102' THEN v_result:='机器工程专业';
            WHEN '151103' THEN v_result:='通信工程专业';
        ELSE
            v_result:='nothing';
        END CASE;
        DBMS_OUTPUT.PUT_LINE('专业: '||to_char(v_result));
    END;
     

    (2)GOTO语句

    PL/SQL提供的GOTO语句,实现将执行流程转移到标号指定的位置

    格式:GOTO<标号>

    GOTO语句后面的语句标号必须符合标识符的规则。

    格式:<<标号>>语句

    例子:使用上面创建的表,手动输入学生的信息到信息表中。 

    SET SERVEROUTPUT ON;
    DECLARE
        id XSB.SID%TYPE;
        name XSB.SNAME%TYPE;
        sex XSB.SEX%TYPE;
        birthday XSB.BIRTHDAY%TYPE;
        profession XSB.PROFESSION%TYPE;
        score XSB.SCORE%TYPE;
        cnt number:=0;
    BEGIN
            LOOP
                INSERT INTO XSB VALUES('&id','&name','&sex','&birthday','&profession','&score');
                cnt:=cnt+1;
                IF cnt>1 THEN
                    GOTO loop_end;
                END IF;
            END LOOP;
        <>
        DBMS_OUTPUT.PUT_LINE('insert successful!');
    END;

    5.异常处理

    (1)预定义异常

    预定义异常是由运行系统产生的。

    PL/SQL中常见的异常
    异常说明
    zero_divide除零发生的异常,例如:当发生v_num/0时,那么会产生除零异常。
    no_date_found如果一个select语句试图基于其条件检索数据,此异常表示不存在满足条件的数据行。
    too_many_rows由于隐式游标每次只能检索一行数据,使用隐式游标时,这个异常可检测到多行数据存在。
    dup_val_on_index如果某索引已有某键列值,若还要在该索引中创建该键码值索引时,出现此异常。例如:假设一个药店系统以发票号为键码,当某个应用程序准备创建一个重复的发票号时,那么会产生此异常。
    value_error此异常表示指定目标域的长度小于待放入其中的数据长度,例如:将“ABCDEFG”字符串放入到定义为“varchar2(3)”中时,那么将会产生此异常。
    case_not_found在case语句中出现不匹配的when语句时,出现此异常。

    例子1:除零发生的异常。

    SET SERVEROUTPUT ON;
    DECLARE
        v_value number(2):=1;
        v_number number(2):=0;
        v_result number(2);
    BEGIN
        v_result:=v_value/v_number;
        EXCEPTION
            WHEN ZERO_DIVIDE THEN
                DBMS_OUTPUT.PUT_LINE('DIVIDE ZERO');
    END;

    例子2:类型转换的错误处理。

    SET SERVEROUTPUT ON;
    DECLARE
        v_value number(5);
        v_result char(5):='6y';
    BEGIN
        v_value:=to_char(v_result);
        EXCEPTION
            WHEN VALUE_ERROR THEN
                DBMS_OUTPUT.PUT_LINE('CONVERT TYPE ERROR');
    END; 

    例子3:联合异常的处理。

     SET SERVEROUTPUT ON;
    DECLARE
        v_value XSB.SID%TYPE;
    BEGIN
        SELECT sid INTO v_value
            FROM XSB
            WHERE sid='&id';
        DBMS_OUTPUT.PUT_LINE('information; '||to_char(v_value));
        EXCEPTION
            WHEN TOO_MANY_ROWS THEN
                DBMS_OUTPUT.PUT_LINE('This is too many rows');
            WHEN NO_DATA_FOUND THEN
                DBMS_OUTPUT.PUT_LINE('not found data');
    END;

     

    (2)用户自定义异常

     EXCEPTION

            WHEN 异常名  THEN

                    语句块1;

            WHEN 异常名  THEN

                    语句块2;

            [WHEN OTHERS THEN

                    语句块3]

    END;

    例子:统计表中的学生数和给定的最大上限进行比较。

    SET SERVEROUTPUT ON;
    DECLARE
        overNumber EXCEPTION;
        v_numLen number(2):=0;
        v_maxvalue number(2):=10;
    BEGIN
        --统计表中的学生数
        SELECT count(*) INTO v_numLen
            FROM XSB;
        --使用REAISE调用异常处理
        IF v_numLen>v_maxvalue THEN
            RAISE overNumber;
        END IF;
        EXCEPTION
            WHEN overNumber THEN
                DBMS_OUTPUT.PUT_LINE('v_numLen: '||to_char(v_numLen)
                ||'  v_maxValue: '||to_char(v_maxvalue));
    END;

    可以使用多个WHEN捕获多个异常,还可以结合系统预定义的异常进行处理。 

    EXCEPTION

            --当出现异常1或者异常2的时候执行语句

            WHEN 异常1 OR 异常2 THEN

            ……

            --当出现异常3的之后执行语句

            WHEN 异常3 THEN

    END;

    使用OTHERS处理异常

    SET SERVEROUTPUT ON;
    DECLARE
        v_value XSB.SID%TYPE;
    BEGIN
        SELECT sid INTO v_value
            FROM XSB
            WHERE sid='&id';
        DBMS_OUTPUT.PUT_LINE('information; '||to_char(v_value));
        EXCEPTION
            WHEN TOO_MANY_ROWS THEN
                DBMS_OUTPUT.PUT_LINE('This is too many rows');
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('implement OTHERS');
    END;

    补充:也可以将上面的OTHERS中的语句块换成下面的语句执行。

    (1)SQLCODE:报告当前错误的代码,如果是用户自定义的异常,那么返回“1”;

    (2)SQLERRM:返回的是当前错误的信息。 


    SET SERVEROUTPUT ON;
    DECLARE
        v_value XSB.SID%TYPE;
    BEGIN
        SELECT sid INTO v_value
            FROM XSB
            WHERE sid='&id';
        DBMS_OUTPUT.PUT_LINE('information; '||to_char(v_value));
        EXCEPTION
            WHEN TOO_MANY_ROWS THEN
                DBMS_OUTPUT.PUT_LINE('This is too many rows');
            WHEN OTHERS THEN
                DBMS_OUTPUT.PUT_LINE('The SQLCODE is: '||SQLCODE);
                DBMS_OUTPUT.PUT_LINE('The SQLERRM is: '||SQLERRM);
    END; 

  • 相关阅读:
    LeetCode 1656. 设计有序流
    一套基于tailwindcss的后台管理系统模板Chakra UI + React + TS
    JavaEE 多线程下的HashTable、HashMap、ConcurrentHashMap
    俄罗斯方块
    ADB 命令大全
    MySQL:表的创建、删除、修改
    结尾:编程指南
    杨辉三角形(Java版)
    仿热血江湖游戏类46获取范围玩家发送地面消失物品数据包
    字节跳动发Seed-TTS语音合成模型,可模仿任意人的声音,效果逼真
  • 原文地址:https://blog.csdn.net/Keep_Trying_Go/article/details/126908889