zoukankan      html  css  js  c++  java
  • Oracle 笔记(四)

    PLSQL编程【语法、plsql控制语句、异常、游标、触发器、存储过程】

    1、              PLSQL的语法–块编程

    a)       概念:procedural language  struct query language

    b)      PLSQL书写语法

    declare

           --声明块

    begin

    --执行块

    exception—异常块

    when XXX异常 then—捕获异常的语法

                  --异常处理

    end;

    c)       变量的定义

    变量名[constant]数据类型 := 初始值;

    d)      数据类型

    Oracle数据类型:integer,number ,varchar2,char……

    --声明一个变量,在变量中存储一个姓名王健,并打印欢迎王健同学来上课

    declare

    v_name varchar2(10);

    begin

      v_name :='王健';

      dbms_output.put_line('欢迎'||v_name||'同学来上课!');

    end;

    会话输出打印开关

    set serveroutput on;

    --声明一个变量,在变量中存储一个姓名王健,并打印欢迎王健同学来上课

    declare

    v_name varchar2(10):='王健' ;

    v_age  number(3):=18;

    begin

      --给变量v_name赋值

      v_name := '&学生姓名';

      v_age := &年龄;

      dbms_output.put_line('欢迎'||v_name||v_age||'同学来上课!');

      end;

    e)       伪类型

    1)      列伪类型emp.ename%type

    2)      行伪类型emp%rowtype

    --编写一段plsql块,完成功能把scott用户的姓名存储到v_ename变量中,工资存储到v_sal变量中并打印变量存储的值

    declare

    v_ename emp.ename%type; --列伪类型

    v_sal  emp.sal%type;

    begin

    select ename,sal into v_ename,v_sal from emp where ename='SCOTT';

      dbms_output.put('员工的姓名:'||v_ename);

      dbms_output.put_line(',员工的工资:'||v_sal);

    end;

    --编写一段plsql块,完成功能把scott用户的所有信息存储并打印出来

    declare

    v_emprow  emp%rowtype;--行伪类型

    begin

    select*into v_emprow from emp where ename ='SCOTT';  dbms_output.put_line(v_emprow.empno||v_emprow.ename||v_emprow.job);

    end;

    f)        变量赋值有几种方式?

    1.:=[初始化、语句赋值]

    2.select 字段名 into 变量名 from 表

    3.替代变量&变量描述

    2、              PLSQL编程控制语句语法–编程思想

    a)       if条件分支

    if 条件 then

           --操作语句

    elsif条件 then

                  --操作语句

    else

    --操作语句

    end if;

    b)      case多分支

    case 比较变量

    when 比较值 then

           --操作语句

    when 比较值 then

           --操作语句

    when 比较值 then

           --操作语句

    when 比较值 then

           --操作语句

    ……

    else

           --缺省值

    end case;

    c)       循环之while循环

    While 循环条件

    Loop

           --执行语句

    end loop;

    d)      循环之dowhile循环 loop循环

    loop

           --执行语句

    Exit when 退出条件

    end loop;

    e)       循环之for循环

    For 循环变量 in 开始值..结束值

    Loop

    end loop;

    f)        Goto :问题-多重循环跳出问题【循环不能超过三层,垃圾代码】

    一、         条件分支语句

    a)       简单的条件判断 if- then

    --编写一个块,可以输入一个雇员名,如果该雇员的工资低于2000,就给该雇员工资增加10%

    declare

    v_ename emp.ename%type;

    v_sal emp.sal%type;

    begin

      v_ename :='&雇员姓名';

    select sal into v_sal from emp_bak where ename=v_ename;

     

    if v_sal<2000then

    update emp_bak set sal= sal*1.1where ename=v_ename;

    endif;

    end;

    a)       二重条件分支 if then else

    --编写一个块,可以输入一个雇员名,如果该雇员的补助不是0就在原来的基础上增加100;如果补助为0就把补助设为200

    --编写一个块,可以输入一个雇员名,如果该雇员的补助不是0就在原来的基础上增加100;

    --如果补助为0就把补助设为200

    declare

    v_ename emp.ename%type;

    v_comm emp.comm%type;

    declare

    v_ename emp.ename%type;

    v_comm emp.comm%type;

    begin

      v_ename :='ALLEN';

    select nvl(comm,0)into v_comm from emp_bak where ename=v_ename;

    if v_comm<>0then

    update emp_bak set comm = comm+100where ename = v_ename;

    else

    update emp_bak set comm =200where ename = v_ename;

    endif;

    end;

    b)      多重条件分支 if-then elsif – else[CASE 实现]

    --编写一个块,可以输入一个雇员编号,如果该雇员的职位是PRESIDENT就给他的工资增加1000,如果该雇员的职位是MANAGER就给他的工资增加500,其它职位的雇员工资增加200

    二、         循环语句– loop

    编写一个过程,可输入用户名,并循环添加10个用户到users表中,用户编号从1开始

    --编写一个过程,可输入用户名,并循环添加10个用户到users表中,用户编号从1开始

     

     

    3、              异常【系统异常、通用异常、自定义异常、应用程序异常】

    a)       系统异常

    --使用替代变量输入数据,实现向emp表插入数据,并在插入前检查是不是违反主键约束,

    declare

    v_empno emp.empno%type;

    v_ename emp.ename%type;

    v_sal  emp.sal%type;

    begin

      v_empno :=&empno;

      v_ename :='&ename';

      v_sal :=&sal;

    insertinto emp_bak(empno,ename,sal)values(v_empno,v_ename,v_sal);

     

    exception

    when Dup_val_on_index then

          dbms_output.put_line('员工编号已经存在!');

    end;

    b)      通用异常【others】SQLCode异常编码  sqlerrm异常错误消息

    --查询?部门的所有员工打印结果

    declare

    v_emprow emp%rowtype;

    v_deptno emp.deptno%type;

    begin

      v_deptno :=&deptno;

    select*into v_emprow from emp where deptno = v_deptno;

     

    exception

    /*

        when No_data_found then

          dbms_output.put_line('输入的部门不存在!');

          when Too_many_rows then

              dbms_output.put_line('返回的行数太多!');

              */

    whenothersthen

                 dbms_output.put_line('错误编号:'||SQLCode||',错误信息:'||SQLErrM);

    end;

    c)       自定义异常

    --编写PLSQL块,完成限制输入的数字范围1到10,并正确处理异常

    declare

    v_num number(2);

    --1、定义一个异常

    MY_ERR exception;

    begin

      v_num :=0;

     

    --2、经过判断后抛出异常.

    if v_num <1or v_num >10then

    raise MY_ERR;

    endif;

     

        dbms_output.put_line(v_num);

     

    --3、捕获异常

    exception

    when MY_ERR then

            dbms_output.put_line('输入的数字必须在1~10之间');

    end;

    d)      应用程序异常反馈

    pragma exception_init(异常名称,sqlcode);

    raise_application_error(sqlcode,sqlerrm) sqlcode错误编码-20000  ~  -20999

    declare

    v_num number(2);

    --1、定义一个异常

    MY_ERR exception;

    pragmaexception_init(MY_ERR,-20001);

    begin

      v_num :=0;

     

    --2、经过判断后抛出异常.

    if v_num <1or v_num >10then

        raise_application_error(-20001,'输入的数字必须在1~10之间');

    endif;

     

        dbms_output.put_line(v_num);

     

    --3、捕获异常

    exception

    whenothersthen

            dbms_output.put_line('错误编号:'||SQLCode||',错误信息:'||SQLErrM);

    end;

    4、              游标cursor-处理多行数据

    a)       隐式游标sql

    b)      显式游标

    c)       动态游标(REF游标)

    d)      公有属性

    %found 影响一行或多行数据的时候此属性为true

    %notfound 没有影响行数此属性为true

    %rowcount  行数

    %isopen  游标的打开

    e)       案例一:隐式游标-修改scott的工资为2000块

    --隐式游标-查询SCOTT的工资并进行打印

    declare

    v_sal emp.sal%type;

    begin

    select sal into v_sal from emp where ename ='SCOTT';

    ifsql%foundthen

        dbms_output.put_line(sql%rowcount);

    endif;

    end;

    --隐式游标-修改30号部门的工资为2000块

    Begin

    update emp_bak set sal =2000where deptno =30;

    ifsql%foundthen

    dbms_output.put_line(sql%rowcount);

    else

    dbms_output.put_line(‘输入的部门编号不存在!’);

    endif;

    end;

    f)        案例二:显式游标-查询30号所有员工信息

    --查询30部门所有员工信息

    declare

    v_emprow emp%rowtype;

    --定义游标

    cursor cur_erow  isselect*from emp where deptno =30;

    begin

    --获取游标

    for v_emprow in cur_erow

    loop

          dbms_output.put_line('雇员姓名:'||v_emprow.ename);

    endloop;

    end;

    案例三:带参显式游标 -显式游标-查询?号所有员工信息

    --查询30部门所有员工信息

    declare

    v_emprow emp%rowtype;

     

    --定义游标

    cursor cur_erow(v_deptno emp.deptno%type)isselect*from emp where deptno = v_deptno;

    begin

    --获取游标

    for v_emprow in cur_erow(&deptno)

    loop

          dbms_output.put_line('雇员姓名:'||v_emprow.ename);

    endloop;

    end;

    练习:将score_bak表中的每个学生的成绩改成这门课的平均成绩

    declare

    v_vwrow vw_avg_scr%rowtype;

    cursor cur_avg isselect*from vw_avg_scr;

    begin

    for v_vwrow in cur_avg

    loop

    update score_bak set scr = v_vwrow.avg_scr where cno = v_vwrow.cno;

    endloop;

    end;

     

    g)       案例四:loop循环游标

    --查询30号部门所有员工信息

    declare

    v_erow emp%rowtype;

    --定义游标

    cursor cur_erow isselect*from emp where deptno =30;

    begin

    --打开游标

    open cur_erow;

    --获取游标

    loop

    fetch cur_erow into v_erow;

        dbms_output.put_line('员工姓名:'||v_erow.ename);

    exitwhen cur_erow%notfound;

    endloop;

    --关闭游标

    if cur_erow%isopenthen

    close cur_erow;

    endif;

    end;

    h)      案例五:动态游标/ref游标

    --使用动态游标打印员工信息和部门信息

    declare

    v_erow emp%rowtype;

    v_drow dept%rowtype;

     

    --1、定义一个动态游标类型

    --弱类型的动态游标

    type cur1 isrefcursor;

    --强类型的动态游标

    type cur2 isrefcursorreturn emp%rowtype;

     

    --2、使用动态游标类型定义一个动态游标

    cur_row  cur1;

    begin

    --3、打开游标并给游标赋值

    open cur_row forselect*from emp;

     

    --4、使用loop循环获取游标

      dbms_output.put_line('员工信息:');

     

    loop

    fetch cur_row into v_erow;

        dbms_output.put_line(v_erow.ename);

    exitwhen cur_row%notfound;

    endloop;

    --5、关闭游标

    if cur_row%isopenthen

    close cur_row;

    endif;

     

    --6、重新打开游标并重新给游标赋值

    open cur_row forselect*from dept;

     

    --7、使用loop循环获取游标

      dbms_output.put_line('部门信息:');

    loop

    fetch cur_row into v_drow;

        dbms_output.put_line(v_drow.dname);

    exitwhen cur_row%notfound;

    endloop;

    --8、关闭游标

    if cur_row%isopenthen

    close cur_row;

    endif;

    end;

     

    1、              Oracle的自定义函数

    2、              Oracle的触发器

    3、              Oracle的存储过程

    知识点一:自定义函数

    语法:create [or replace] function 函数名(参数)

                  return返回值类型—必须

                  is

           --变量的声明

    begin

           --执行语句

           --return 返回变量

           --exception 异常块(return 异常编号)

                  end;

    Java:

    int add(int no1,int no2)

    {

       int sum = no1+no2;

       return sum;

    }

    Oracle

    --使用PLSQL developer创建自定义函数,实现两个数字相加

    createorreplacefunction fun_add(num1 number,num2 number)

    returnnumber

    is

    v_result number(2);

    begin

      v_result := num1+num2;

    return v_result;

     

    exception

    whenothersthen

                 dbms_output.put_line('输入错误!');

    return-1;

    end;

     

    调用函数

    方式一:

    select fun_add(50,50) from dual;

    方式二:

    declare

    v_num1 number(2);

    v_num2 number(2);

    v_result number(2);

    begin

      v_num1 :=&加数1;

      v_num2 :=&加数2;

      v_result := fun_add(v_num1,v_num2);

     

      dbms_output.put_line(v_result);

    exception

    whenothersthen

                   dbms_output.put_line('输入的数据有误!!');

    end;

     2017-10-31 18:36:17

  • 相关阅读:
    作业信息获取
    SQL Server数据库性能监控计数器
    c# 索引器學習
    C# DataGridView 小技巧
    C# DataTable 小技巧
    c# 小技巧
    C# new,Virtual,abstract,sealed,Override的簡單理解
    C# 位操作符
    C# 類型小技巧
    C# partial 局部类型
  • 原文地址:https://www.cnblogs.com/angelye/p/7762949.html
Copyright © 2011-2022 走看看