zoukankan      html  css  js  c++  java
  • Oracle基础进阶

    PL/SQL

      是Oracle对sql语言的过程化扩展,指在sql命令语言中增加了过程处理语句,是sql语言具有过程处理能力.
    语法:
      [declare
        --声明变量
      ]
      begin
      --逻辑代码
      [exception
        --异常处理
      ]

    变量:

      声明变量的语法:变量名 类型(长度)
      变量赋值的语法:变量名:=变量值

    例如

    declare
      v_price number(10,2);--单价
      v_usenum number;--水费数字
      v_usenum2 number(10,2);--吨数
      v_money number(10,2);--总价
    begin
      v_price:=2.45;
      v_usenum:=3306;
      v_usenum2:=round(v_usenum/1000,2);
      v_money:=v_usenum2*v_price;
      DBMS_output.put_line('总价:'||v_money);
    end;

    对于变量的赋值,还 可以用:select into方式赋值 select 列名 into 变量名 from 表名 where 条件
    但是这种方式的结果必须是一条记录,有多条记录和没有记录都会报错

    这里就可以吧上面的水费的数字改成从已经有的表中查找出来

    select usernum into v_usenum from t_account where owneruuid=1;

    属性类型分为引用型和记录型,首先介绍引用型
      %type(引用型):引用某表某列的字段类型
    还是上面的例子,水费数字的number可以改为指定表中指定列的引用型类型

    v_usenum t_account.usenum%type;

    %rowtype(记录型):表示某个表的行记录类型
    依旧上面的例子,水费数字等数据可以被替代为:

    v_account t_account%rowtype;

    这个赋值可以看做是为一个对象赋值一行数据,而这个对象在这里就是v_account

    赋值语句:

    select * into v_account from t_account where owneruuid = 1;

    这样在后面使用的时候直接点调用里面需要的数据
    比如要调用水费数字:
    v_account.usenum;这就得到了水费数字在原表中的数据

    异常:

      在运行程序时出现的错误叫做异常
    发生异常后,语句将停止执行,控制权转移到PL/SQL块的异常处理部分.
    在这里介绍两个预定义异常,预定义异常就是当PL/SQL程序违反Oracle规则或超越系统限制时隐式引发

    首先介绍第一个:

    NO_DATA_FOUND:使用select into未返回行
    TOO_MANY_ROWS:执行select into时,结果集超过一行

    exception
      when 异常类型 then
        异常处理逻辑

    还是以上面的为例子,模拟在给水费数字赋值的时候,select into未返回行

    ...
    begin
    exception
        when NO_DATA_FOUND then
        dbms_output.put_line('没有返回数据');
    end;
    如果在再此基础上添加一个超过结果集的异常,那么
    ...
    begin
    exception
        when NO_DATA_FOUND then
        dbms_output.put_line('没有返回数据');
        when TOO_MANY_ROWS then
        dbms_output.put_line('返回信息过多');
    end;

    条件判断

      基本语法1:

    if 条件 then
      业务逻辑
    end if;

      基本语法2:

    if 条件 then
      业务逻辑
    else
      业务逻辑
    end if;

    基本语法3:

    if 条件 then
      业务逻辑
    elsif 条件 then
      业务逻辑
    else
      业务逻辑
    end if;

    下面是一个前面综合的完整列子:

      5 吨以下 2.45 元/吨 5 吨到 10 吨部分 3.45 元/吨 ,超过 10 吨部分 4.45 ,根据使用水费的量来计算阶梯水费。

    declare
        v_price1 number(10,2);-- 不足 5 吨的单价
        v_price2 number(10,2);-- 超过 5 吨不足 10 吨单价
        v_price3 number(10,2);-- 超过 10 吨单价
        v_account T_ACCOUNT%ROWTYPE;-- 记录型
        v_usenum2 number(10,2);-- 使用吨数
        v_money number(10,2);-- 水费金额
    begin
    -- 对单价进行赋值
        v_price1:=2.45;
        v_price2:=3.45;
        v_price3:=4.45;
        -- 给v_account赋值
        select * into v_account from T_ACCOUNT
        where year='2012' and month='01' and owneruuid=1;
        -- 使用吨数
        v_usenum2:= round(v_account.usenum/1000,2);
    -- 计算金额 ( 阶梯水费 )
        if v_usenum2<=5 then-- 第一个阶梯
            v_money:=v_price1*v_usenum2;
        elsif v_usenum2>5 and v_usenum2<=10 then -- 第二个阶梯
            v_money:=v_price1*5 + v_price2*( v_usenum2-5);
        else -- 第三个阶梯
            v_money:=v_price1*5 +v_price2*5 + v_price3*( v_usenum2-10 );
        end if;
    DBMS_OUTPUT.put_line('金额' || v_money);
    
    exception
        when NO_DATA_FOUND then
            DBMS_OUTPUT.put_line('没有找到数据');
        when TOO_MANY_ROWS then
            DBMS_OUTPUT.put_line('返回的数据有多行');
    end;

    循环:

    下面是用1-100的循环例子解释三种不同的循环

      无条件循环(语法):

    loop
      -- 循环语句
    end loop;

    第一种解法:

    declare
        v_num number:=1;
    begin
        loop
            dbms_output.put_line(v_num);
            v_num:=v_num+1;
            exit when v_num>100;
        end loop;
    end ;

    条件循环(语法):

    while 条件
      loop
    end loop;

    第二种解法:

    declare
        v_num number:=1;
    begin
        while v_num<=100
        loop
            dbms_output.put_line(v_num);
            v_num:=v_num+1;
        end loop;
    end ;

    for循环(语法):

    for 变量 in 起始值..终止值
      loop
    end loop;

    第三种解法:

    begin
        for v_num in 1..100
        loop
            dbms_output.put_line(v_num);
        end loop;
    end;

    游标:

      游标是系统为用户开设的一个数据缓冲区,存放sql语句的执行结果,可以把游标理解为PL/SQL中的结果集

    声明游标的语法:

      cursor 游标名称 is SQL 语句;

    使用游标的语法:

    open 游标名称
      loop
      fetch 游标名称 into 变量
      exit when 游标名称%notfound
    end loop;

    close 游标名称;

    下面的例子使用scott用户操作Oracle中的默认emp表

    declare
        --定义游标
        cursor cemp is select ename,sal from emp;
        --定义变量
        vename emp.ename%type;
        vsal   emp.sal%type;
    begin
        --打开游标,这时游标位于第一条记录之前
        open cemp;
        --循环
        loop
           --向下移动游标一次
           fetch cemp into vename,vsal; 
           --退出循环,当游标下移一次后,找不到记录时,则退出循环
           exit when cemp%notfound;
           --输出结果
           dbms_output.put_line(vename||'--------'||vsal);
        end loop;
        --关闭游标
        close cemp;
    end;

    存储函数

      存储函数就是自定义函数,可以接收一个或多个参数,返回一个结果,在函数中我们可以使用P/SQL进行逻辑的处理
    创建或修改存储过程的语法:

    CREATE [ OR REPLACE ] FUNCTION 函数名称
    (参数名称 参数类型, 参数名称 参数类型, ...)
    RETURN 结果变量数据类型
    IS
        变量声明部分;
    BEGIN
        逻辑部分;
        RETURN 结果变量;
    [EXCEPTION
        异常处理部分]
    END;

    下面几个例子:

      创建存储函数,根据地质id查询地址名称

    create function fn_getaddress(v_id number)
    return varchar2
    is
        v_name varchar2(30);
    begin
        select name into v_name from t_address where id=v_id;
        return v_name;
    end;

    测试函数:

    select fn_getaddress(3) from dual;

    存储过程

      存储过程是被命名的PL/SQL块,存储于数据库中,是数据库对象的一种.

    存储过程语法如下:

    CREATE [ OR REPLACE ] PROCEDURE 存储过程名称
        (参数名 类型, 参数名 类型, 参数名 类型)
    IS|AS
        变量声明部分;
    BEGIN
        逻辑部分
    [EXCEPTION
        异常处理部分]
    END;

    过程参数的三种模式:

    IN 传入参数(默认)
    OUT 传出参数,主要用于返回程序运行结果
    IN OUT 传入传出参数

    带传出参数的存储过程

    -- 增加业主信息序列
    create sequence seq_owners;
    create or replace procedure pro_owners_add
    (
        v_name varchar2,
        v_addressid number,
        v_housenumber varchar2,
        v_watermeter varchar2,
        v_type number,
        v_id out number
    )
    is
    begin
        select seq_owners.nextval into v_id from dual;
        insert into T_OWNERS
        values( v_id,v_name,v_addressid,v_housenumber,v_watermete
        r,sysdate,v_type );
        commit;
    end;

    PL/SQL 调用该存储过程:

    declare
        v_id number;-- 定义传出参数的变量
    begin
        pro_owners_add('王旺旺',1,'922-3','133-7',1,v_id);
        DBMS_OUTPUT.put_line('增加成功,ID:'||v_id);
    end;

    触发器

      数据库触发器是一个与表相关联的,存储的PL/SQL程序,每当一个特定的数据操作语句(insert,update,delete)在
    指定的表上发出时,Oracle自动地执行触发器中定义的语句序列

      触发器分为前置触发器(before)和后置触发器(after)

    创建触发器的语法:

    CREATE [or REPLACE] TRIGGER 触发器名
        BEFORE | AFTER
        [DELETE ][[or] INSERT] [[or]UPDATE [OF 列名]]
        ON 表名
        [FOR EACH ROW ][WHEN(条件) ]
    declare
    ……
    begin
        PLSQL 块
    End

    在触发器中触发语句与伪记录变量的值

    触发语句  :old  :new
    Insert      所有字段都是空(null)          将要插入的数据
    Update      更新以前该行的值          更新后的值
    delete      删除以前该行的值          所有字段都是空(null)

    前置触发器案例:

    创建语句级触发器insertEmpTrigger,当对表【emp】进行增加【insert】操作前【before】,显示"hello world"

    create or replace tirgger insertEmpTrigger
    before
    insert
    on emp
    begin
        dbms_output.put_line('hello wordl');
    end;
  • 相关阅读:
    Android笔记——UI开发
    P2P网络借贷系统-核心功能-用户投标-业务解说
    java回调简单实现
    Java面向对象编程(二)
    POJ-1190-生日蛋糕-DFS(深搜)-枚举-多重剪枝
    设计模式笔记——装饰模式
    bbed初体验
    高速理解环境变量
    最短路算法之 Dijkstra算法
    C++课程资源下载问题
  • 原文地址:https://www.cnblogs.com/learnjfm/p/7087454.html
Copyright © 2011-2022 走看看