• Oracle_PL/SQL(2) 过程控制


    0.检索单行数据
    0.1使用标量变量接受数据
    例1: 7788
    declare
    v_ename emp.ename%type;
    v_sal emp.sal%type;
    begin
    select ename,sal into v_ename,v_sal from emp where empno=&no;
    dbms_output.put_line('职员号:'||&no||' 职员名:'||v_ename);
    end;

    0.2嵌入SELECT语句注意事项:
    使用SELECT INTO语句时,必须要返回一条数据,并且只能返回一条数据
    no_date_found:
    select into没有返回数据
    too_many_rows:
    select into返回多条数据
    例2:
    declare
    v_ename emp.ename%type;
    v_sal emp.sal%type;
    begin
    select ename,sal into v_ename,v_sal from emp where deptno=&deptno;
    dbms_output.put_line('部门编号:'||&deptno||' 职员名:'||v_ename);
    end;
    where子句使用注意事项:
    使用的变量名不能与列名相同,否则触发TOO_MANY_ROWS例外.
    例3:
    declare
    v_ename emp.ename%type;
    v_sal emp.sal%type;
    empno emp.empno%type;
    begin
    empno:=&no;
    select ename,sal into v_ename,v_sal from emp where empno=empno;
    dbms_output.put_line('职员编号:'||&no||' 职员名:'||v_ename);
    end;


    PL/SQL控制结构
    1.按顺序执行语句
    declare
    v_sal number;
    v_avg number;
    begin
    select avg(sal) into v_avg from emp;
    dbms_output.put_line('平均工资:'||v_avg);
    select sal into v_sal from emp where empno=7788;
    dbms_output.put_line('职员号7788人员的工资:'||v_sal);
    end;

    2.条件分支语句
    2.1简单条件判断
    语法1:
    if 逻辑表达式1 then
    语句1;
    end if;
    例1:
    declare
    v_sal number;
    v_avg number;
    begin
    select avg(sal) into v_avg from emp;
    select sal into v_sal from emp where empno=7788;
    if v_sal>v_avg then
    dbms_output.put_line('职员号7788人员的工资'||v_sal||'大于平均工资'||v_avg);
    end if;
    end;
    例2:接收参数
    declare
    v_sal number(6,2);
    begin
    select sal into v_sal from emp where lower(ename)=lower('&name');
    dbms_output.put_line('输入的员工姓名是:'||'&name');
    if v_sal<2000 then
    update emp set sal=v_sal+200 where lower(ename)=lower('&name');
    dbms_output.put_line('给员工:'||'&name'||'工资增加了200.');
    end if;
    end;

    2.2二重条件分支
    语法2:
    if 逻辑表达式1 then
    语句1;
    else
    语句2;
    end if;
    例1:
    declare
    v_sal number;
    v_avg number;
    begin
    select avg(sal) into v_avg from emp;
    select sal into v_sal from emp where empno=7788;
    if v_sal>v_avg then
    dbms_output.put_line('职员号7788人员的工资'||v_sal
    ||'大于平均工资'||v_avg);
    else
    dbms_output.put_line('职员号7788人员的工资'||v_sal
    ||'小于等于平均工资'||v_avg);
    end if;
    end;
    例2:接收参数 7788
    declare
    v_comm number(6,2);
    begin
    select comm into v_comm from emp where empno=&no;
    dbms_output.put_line('输入的员工编号是:'||'&no');
    if v_comm is null then
    update emp set comm=200 where empno=&no;
    dbms_output.put_line('给员工编号是:'||'&no'||'的发200奖金.');
    else
    update emp set comm=comm+100 where empno=&no;
    dbms_output.put_line('给员工编号是:'||'&no'||'奖金增加了100.');
    end if;
    end;

    2.3多重条件分支
    语法3:
    if 逻辑表达式1 then
    语句1;
    elsif 逻辑表达式2 then
    语句2
    ...
    else
    语句3;
    end if;
    例1:
    declare
    v_sal number;
    v_avg number;
    begin
    select avg(sal) into v_avg from emp;
    select sal into v_sal from emp where empno=7788;
    if v_sal>v_avg then
    dbms_output.put_line('职员号7788人员的工资'||v_sal
    ||'大于平均工资'||v_avg);
    elsif v_sal<v_avg then
    dbms_output.put_line('职员号7788人员的工资'||v_sal
    ||'小于平均工资'||v_avg);
    else
    dbms_output.put_line('职员号7788人员的工资'||v_sal
    ||'等于平均工资'||v_avg);
    end if;
    end;

    例2:接收参数 7788
    declare
    v_empno number;
    v_job emp.job%type;
    begin
    v_empno:=&no;
    select lower(job) into v_job from emp where empno=v_empno;
    dbms_output.put_line('输入的员工编号是:'||'&no');
    if v_job='manager' then
    update emp set comm=nvl(comm,0)+200 where empno=v_empno;
    dbms_output.put_line('按照员工的职位'||v_job||'给员工编号是:'
    ||v_empno||'奖金增加了200.');
    elsif v_job='analyst' then
    update emp set comm=nvl(comm,0)+100 where empno=v_empno;
    dbms_output.put_line('按照员工的职位'||v_job||'给员工编号是:'
    ||v_empno||'奖金增加了100.');
    else
    update emp set comm=nvl(comm,0)+50 where empno=v_empno;
    dbms_output.put_line('按照员工的职位'||v_job||'给员工编号是:'
    ||v_empno||'奖金增加了50.');
    end if;
    end;

    2.4 CASE语句:
    在CASE语句中使用单一选择符进行等值比较
    语法1:
    case 表达式
    when 表达式1 then 语句1; --表达式与表达式1相等时执行语句1
    when 表达式2 then 语句2; --同上
    ...
    else
    默认语句; --表达式与上述各表达式都不相等时执行默认语句
    end case;
    例1:
    declare
    v_deptno emp.deptno%type;
    begin
    v_deptno:=&no;
    dbms_output.put_line('输入的部门编号是:'||v_deptno);
    case v_deptno
    when 10 then
    update emp set comm=100 where deptno=v_deptno;
    dbms_output.put_line('给部门编号'||v_deptno||'的职员是发100元奖金');
    when 20 then
    update emp set comm=80 where deptno=v_deptno;
    dbms_output.put_line('给部门编号'||v_deptno||'的职员是发80元奖金');
    when 30 then
    update emp set comm=50 where deptno=v_deptno;
    dbms_output.put_line('给部门编号'||v_deptno||'的职员是发50元奖金');
    else
    dbms_output.put_line('部门编号不存在');
    end case;
    end;

    2.5 在CASE语句中使用多种条件比较
    语法2:
    case
    when 逻辑表达式1 then 语句1; --逻辑表达式1为真时执行语句1
    when 逻辑表达式2 then 语句2; --同上
    ...
    else
    默认语句; --上述各逻辑表达式都不为真时执行默认语句
    end case;

    例2:
    declare
    v_empno emp.empno%type;
    v_sal emp.sal%type;
    begin
    v_empno:=&no;
    dbms_output.put_line('输入的职员编号是:'||v_empno);
    select sal into v_sal from emp where empno=v_empno;
    case
    when v_sal<1000 then
    update emp set comm=100 where empno=v_empno;
    dbms_output.put_line('给工资'||v_sal||'小于1000的职员发100元奖金');
    when v_sal<2000 then
    update emp set comm=80 where empno=v_empno;
    dbms_output.put_line('给工资'||v_sal||'小于2000的职员发80元奖金');
    when v_sal<3000 then
    update emp set comm=50 where empno=v_empno;
    dbms_output.put_line('给工资'||v_sal||'小于3000的职员发50元奖金');
    else
    dbms_output.put_line('给工资大于等于3000的职员不发奖金');
    end case;
    end;


    3.循环语句
    分类:loop循环,while循环,for循环
    create table temp_table (
    num_col number(8),
    char_col varchar2(200)
    );

    3.1 loop循环
    语法:
    loop
    语句;
    end loop;
    loop循环没有退出条件,语句被无限次地执行。
    一定要包含EXIT语句,定义循环控制变量,并在循环体内改变循环控制变量的值。
    循环退出exit
    exit when 条件;
    if 条件 then
    exit;
    end if;

    declare
    v_counter number:=1;
    begin
    loop
    insert into temp_table values (v_counter,'loop循环');
    v_counter:=v_counter+1;
    if v_counter>=10 then
    exit;
    end if;
    --exit when v_counter>50;
    end loop;
    end;

    3.2 while循环
    语法:
    while 条件 loop
    语句;
    end loop;

    每次循环前对条件进行判断,条件为真则语句被执行;否则循环终止。
    declare
    v_counter number:=1;
    begin
    while v_counter<=50 loop
    insert into temp_table values (v_counter,'while循环');
    v_counter:=v_counter+1;
    end loop;
    end;

    while中仍可以使用exit退出循环。
    declare
    v_counter number:=1;
    begin
    while v_counter<=50 loop
    insert into temp_table values (v_counter,'while循环exit');
    v_counter:=v_counter+1;
    exit when v_counter>20;
    end loop;
    end;

    3.3 数字式FOR循环
    使用FOR循环时,ORACLE会隐含定义循环控制变量.
    语法:
    for counter in[reverse] lower_bound..upper_bound loop
    statement1;
    statement2;
    .......
    end loop;
    counter是循环控制变量,并且该变量由ORACLE隐含定义,不需要显示定义;
    lower_bound和upper_bound分别对应循环控制变量的上下界值.
    默认情况下,FOR循环,每次会自动增一,指定REVERSE选项时,每次循环控制变量会减一
    例1:
    begin
    for v_counter in 1..10 loop
    insert into temp_table values (v_counter,'for循环');
    end loop;
    end;
    例2:reverse 从大向小循环
    begin
    for v_counter in reverse 1..10 loop
    insert into temp_table values (v_counter,'for循环reverse');
    end loop;
    end;

    3.4 隐式游标for循环
    begin
    for rs in (select * from emp) loop
    insert into temp_table values (rs.empno,rs.ename);
    end loop;
    end;

    begin
    for rs in (select * from emp where deptno=10 ) loop
    if rs.deptno=10 then
    update emp set sal=sal*1.1 where empno=rs.empno;
    end if;
    end loop;
    end;

    3.5 嵌套循环
    例1:2层for循环
    declare
    result number;
    begin
    for i in 1..10 loop
    for j in 1..10 loop
    result:=i*j;
    dbms_output.put_line(i||' * '||j||' = '||result);
    end loop;
    end loop;
    end;

    例2:乘法口诀表
    declare
    n_result number;
    v_result varchar2(2);
    begin
    for i in 1..9 loop
    for j in 1..i loop
    n_result:=j*i;
    if n_result<10 and j<>1 then
    v_result:=n_result||' ';
    else
    v_result:=n_result;
    end if;
    dbms_output.put(j||'*'||i||'='||v_result||' ');
    end loop;
    dbms_output.put_line('');
    end loop;
    end;

    4.退出循环
    4.1 continue 退出本次循环(10G以上版本)
    begin
    for v_counter in 1..50 loop
    if v_counter>20 and v_counter<=30 then
    continue;
    else
    insert into temp_table values (v_counter,'for循环continue');
    end if;
    end loop;
    end;

    4.2 exit 退出本层循环
    begin
    for v_counter in 1..50 loop
    if v_counter>10 then
    exit;
    else
    insert into temp_table values (v_counter,'for循环exit');
    end if;
    end loop;
    end;
    嵌套循环和标号:通过在嵌套循环中使用标号,可以区分内层循环和外层循环,
    并且可以在内层循环中直接退出外层循环
    例3:
    declare
    n_result number;
    begin
    <<outer>>
    for i in 1..10 loop
    <<inter>>
    for j in 1..10 loop
    n_result:=i*j;
    dbms_output.put_line('内层循环内输出:'||n_result);
    -- exit inter when j=8;
    -- exit outer when n_result=30;
    end loop inter;
    dbms_output.put_line('内、外层循环间输出:'||n_result);
    end loop outer;
    dbms_output.put_line('外层循环外输出:'||n_result);
    end;

    4.3 goto 用于跳转到特定标号处去执行语句.
    declare
    i int :=1;
    begin
    loop
    insert into temp_table values(i,'loop循环+goto');
    if i=10 then
    goto end_loop;
    end if;
    i:=i+1;
    end loop;
    <<end_loop>>
    dbms_output.put_line('循环结束');
    end;

    5.操纵数据
    5.1使用VALUES子句插入数据
    declare
    v_deptno dept.deptno%type;
    v_dname dept.dname%type;
    begin
    v_deptno:=&no;
    v_dname:='&name';
    insert into dept (deptno,dname) values(v_deptno,v_dname);
    end;

    5.2使用子查询插入数据
    --复制表结构,不带数据
    create table employee as select * from emp where 1=2;
    --
    declare
    v_deptno emp.deptno%type:=&no;
    begin
    insert into employee select * from emp where deptno=v_deptno;
    end;

    5.3更新数据
    使用表达式更新列值
    declare
    v_deptno dept.deptno%type:=&no;
    v_loc dept.loc%type:='&loc';
    begin
    update dept set loc=v_loc where deptno=v_deptno;
    end;

    5.4使用子查询更新列值 MILLER
    declare
    v_ename emp.ename%type:='&name';
    begin
    update employee set (sal,comm) =
    (select sal,comm from emp where ename=v_ename)
    where job = (select job from emp where ename=v_ename)
    end;

    5.5删除数据
    使用变量删除数据
    declare
    v_deptno dept.deptno%type:=&no;
    begin
    delete from dept where deptno=v_deptno;
    end;

    5.6使用子查询删除数据
    declare
    v_ename emp.ename%type:='&name';
    begin
    delete from employee where deptno=
    (select deptno from emp where ename=v_ename);
    end;

    6.事务控制语句
    事务控制语句包括commit,rollback以及savepoint等三种语句
    例1:
    declare
    v_sal emp.sal%type:=&salary;
    v_ename emp.ename%type:='&name';
    begin
    update emp set sal=v_sal where lower(ename)=v_ename;
    select sal into v_sal from emp where ename=v_ename;
    dbms_output.put_line(v_sal);
    commit;
    exception
    when others then
    --dbms_output.put_line('发生了运行时异常');
    --raise_application_error(-20001,'发生了运行时异常');
    rollback;
    end;

    例2:
    declare
    begin
    insert into temp_table values(1,'事务控制语句');
    savepoint a1;
    insert into temp_table values(2,'事务控制语句');
    savepoint a2;
    insert into temp_table values(3,'事务控制语句');
    savepoint a3;
    rollback to a2;
    commit;
    end;

  • 相关阅读:
    mysql in 的两种使用方法
    Cocos2d-x游戏中默认的AndroidManifest.xml的解析
    UVA 11551
    本周游戏体验:卧虎藏龙
    Android.mk各种文件编译汇总
    hdu 寒冰王座
    树的专题整理(二)
    leetcode 题解 || Swap Nodes in Pairs 问题
    接上SQL SERVER的锁机制(一)——概述(锁的种类与范围)
    SQL SERVER的锁机制(一)——概述(锁的种类与范围)
  • 原文地址:https://www.cnblogs.com/BradMiller/p/9279576.html
Copyright © 2020-2023  润新知