• Oracle在触发器中自定义异常以及修改列的值


     
    一:存储过程的定义
        1>过程(多次编译 多次执行):
           --过程实现计算器
           declare p1 number:=1;
           p2 number:=2;
           sign varchar2(3):='-';
           begin
             if sign='+' then
                syso(p1+p2);
             elsif(sign='-' ) then
                syso(p1-p2);
             elsif(sign='*' ) then
                syso(p1*p2);
             elsif(sign='/' ) then
                syso(p1/p2);
             end if;
           end;
        2>存储过程(一次编译 多次执行)
           --存储过程的定义  
           --存储过程执行只是编译的过程  如果需要执行存储过程的代码 需要在过程中调用
           create or replace procedure pro_arthirm(p1 number,p2 number,sign varchar2) 
           as
           --参数的定义
           begin
           --过程体
             if sign='+' then
                syso(p1+p2);
             elsif(sign='-' ) then
                syso(p1-p2)
             elsif(sign='*' ) then
                syso(p1*p2);
             elsif(sign='/' ) then
                syso(p1/p2);
             end if;
           end;
           --在plsql中调用存储过程
           declare p1 number:=1;
           p2 number:=2;
           sign varchar2(3):='+';
           begin
                pro_arthirm(p1,p2,sign);
           end;
                     
           --在command模式下  需要使用  
           call 过程名称(参数。。。)
           execute(exec) 过程名称(参数。。。)
           show errors 显示存储过程编译之后的错误
          
           
       3>存储过程参数
           /**    参数类型:
               IN 输入参数。只能获取它的值 不能修改他的值 调用设置的值 可以在存储过程中查看
               OUT 输出参数。只能在过程体中赋值 不能查看到传入的值
               IN OUT 输入输出参数。可以取它的值,也可以给它赋值
               
               public int arthirm(int p1,int p2,String sign){
                  int returnNum=5;
                  if(...){
                     returnNum=p1+p2
                  }
                  return returnNum;
               }
               **/
               
               create or replace procedure pro_arthirmByReturn(p1 in number,p2 in number,sign in varchar2,returnNum in out number) 
                   as
                   --参数的定义
                   rtnNum number;
                   begin
                   syso(returnNum);
                   --过程体
                     if sign='+' then
                        returnNum:=(p1+p2);
                     elsif(sign='-' ) then
                        returnNum:=(p1-p2);
                     elsif(sign='*' ) then
                        returnNum:=(p1*p2);
                     elsif(sign='/' ) then
                        returnNum:=(p1/p2);
                     end if;
                   end;
                 
                 declare p1 number:=1;
                   p2 number:=2;
                   sign varchar2(3):='+';
                   returnNumber number:=10;
                   begin
                        pro_arthirmByReturn(p1,p2,sign,returnNumber);
                      syso(returnNumber);
                   end;
          4>查询数据库的对象的三中方式
          select count(*) from user_procedures;--当前用户的存储过程
          select count(*) from all_procedures; --相同权限的用户所有的存储过程 权限下有多少存储过程就输出多少 不会有编译出错
           select count(*) from dba_procedures; --系统所有的存储 如果没有dba的权限会编译出错
          5>删除存储过程
           drop procedure 存储过程名称 
    二:函数过程的定义  
          CREATE [OR REPLACE] FUNCTION 函数名
           [(参数名 [IN|OUT|IN OUT] 数据类型[, …])]
           RETURN 返回值类型
           {IS | AS}
           BEGIN
               函数的主体
           END [函数名];
             函数和存储过程的区别在于
             1  函数可以返回值  存储过程不行
             2  函数可以在sql中使用 存储过程不行
             3  函数是一种特殊的存储过程
            例子 
            create or replace function  fun_arthirmbyDeclare(p1 in number,p2 in number,sign in varchar2)
               return number
                       as
                              
               resultDNum number;
                       begin
                            
                         if sign='+' then
                            resultDNum:=(p1+p2);
                         elsif(sign='-' ) then
                            resultDNum:=(p1-p2);
                         elsif(sign='*' ) then
                            resultDNum:=(p1*p2);
                         elsif(sign='/' ) then
                            resultDNum:=(p1/p2);
                         end if;
                 return resultDNum;
                       end;
               --调用函数    
              declare p1 number:=1;
                       p2 number:=2;
                       sign varchar2(3):='+';
                       returnNumber number;
                       begin
                            returnNumber:=fun_arthirmbyDeclare(p1,p2,sign);
                          syso(returnNumber);
                       end;
               --删除函数:
               DROP FUNCTION 函数名;
                           
            区分存储过程和函数在user_procedures
          select object_name,object_type from user_objects where object_name in(select object_name from user_procedures)        
    三:触发器的定义         
        CREATE [OR REPLACE] TRIGGER 触发器名
           [BEFORE | AFTER] 激活触发器的事件(insert,update,delete)
           ON 表名
           [FOR EACH ROW]  -- 指定为行级触发器
           [WHEN 触发条件]
           BEGIN
               主体;
           END [触发器名];
           /
          注意:
       多种激活触发器用or来连接:insert or update or delete
       在触发器主体语句中可以用“inserting”、“updating”、“deleting”判断激活事件。
       在行级触发器中,可以通过:old和:new别名访问列的原值和新值。 
       举例:
         create or replace trigger trg_grade_delete before
           delete on tb_grade
           FOR EACH ROW
           begin
              /**
                 在dml操作中 数据的修改是存在新和旧的问题
                 insert语句  只有新的数据
                 delete语句  只有旧的数据
                 update语句  有新和旧的问题
                 oracle通过var变量的方式存储新旧值
                 :new
                 :old 只能使用在行级触发器上
              **/
              syso('我删除了一行记录 班级名称是:'||:old.cname );
           
           end;   
          delete from tb_grade where cid=3;
        演示在触发器中自定义异常以及修改列的值
            create table orders(
              id number primary key,
              sname varchar2(20),
              price number,
              total number,
              totalPrice number
           )
            --在before触发器中可以修改:new的值 after不行
            create or replace trigger trg_orders before
                   insert on orders
                   FOR EACH ROW
               declare
               rollbackException exception;  --自定义异常
                   begin
                  --判断价格小于0  不满足 应该回滚
                  if :new.price<0 then
                      raise rollbackException;
                  end if;
                  --总价=单价*数量
                  :new.totalPrice:=:new.price*:new.total;
                  /**
                  exception when rollbackException then
                     syso('判断价格小于0');
                  **/   
               end;
                         
  • 相关阅读:
    A 【NOIP2012 day2】疫情控制
    Leetcode(886)-可能的二分法
    判断链表是否有环
    如何判断图的连通
    图的DFS与BFS
    struct 和 class的区别
    最小生成树-kruskal算法
    Leetcode(712)-账户合并
    全局最小割
    Leetcode(29)-两数相除
  • 原文地址:https://www.cnblogs.com/t0404/p/10291063.html
Copyright © 2020-2023  润新知