PLSQ编程

PLSQ编程

PLSQ编程

流程控制:

判断语句 if

循环语句 loop exit while for

顺序语句 goto null

判断语句 if

IF <布尔表达式> THEN
  PL/SQL 和 SQL语句
  END IF;
   
  IF <布尔表达式> THEN
  PL/SQL 和 SQL语句
  ELSE
  其它语句
  END IF;
   
  IF <布尔表达式> THEN
  PL/SQL 和 SQL语句
  ELSIF < 其它布尔表达式> THEN
  其它语句
  ELSIF < 其它布尔表达式> THEN
  其它语句
  ELSE
  其它语句
  END IF;

根据用户输入的用户编号,确定用户的工资等级

 --根据用户输入的用户编号,确定用户的工资等级
  declare
    v_empno emp.empno%Type:=&v_empno;
    v_sal emp.sal%type;
   begin
           
     select sal into v_sal from emp where empno=v_empno;
     dbms_output.put_line(v_sal);
     if v_sal <1500 then
       dbms_output.put_line('工资等级为1级');
      elsif v_sal <3000 then 
        dbms_output.put_line('工资等级为2级');
       else
         dbms_output.put_line('工资等级为3级');
     end if;
   end;

循环语句 loop exit while for

简单循环:loop

LOOP 要执行的语句; EXIT WHEN <条件语句> /条件满足,退出循环语句/END LOOP;

 --输出1--10
  declare
    v_i number :=1;
   begin
     loop 
       dbms_output.put_line(v_i);
       v_i:=v_i+1;
       exit when v_i > 10;--当满足条件的时候 结束循环
      
     end loop;
   end;

while循环:

WHILE <布尔表达式> LOOP 要执行的语句;END LOOP;

  --输出1--10
  declare
    v_i number := 1;
  ​
  begin
    while v_i <= 10 loop --当满足条件的时候  执行循环
      dbms_output.put_line(v_i);
      v_i := v_i + 1;
     end loop;
  end;

FOR循环(数字式循环)

FOR 循环计数器 IN [ REVERSE ] 下限 .. 上限 LOOP 要执行的语句;END LOOP;

  declare 
     v_i number := 1;
  begin
    for v_i in 1 .. 10 loop
      
        dbms_output.put_line(v_i);
      end loop;
  end;
  ​
  declare 
     v_i number := 1;
  begin
    for v_i in reverse 1 .. 10 loop
      
        dbms_output.put_line(v_i);
      end loop;
  end;
  declare 
     v_i number := 1;
  begin
    for v_i in reverse 1 .. 10 loop
        
        if v_i = 5 then
         exit;--退出循环
        end if;
        dbms_output.put_line(v_i);
        
      end loop;
  end;

null语句

  declare 
     v_i number := 1;
  begin
    for v_i in reverse 1 .. 10 loop
        
        if v_i = 5 then
          
          null;--表示什么都不做
           -- exit;退出循环
        end if;
        dbms_output.put_line(v_i);
        
      end loop;
  end;

异常处理

异常情况处理(EXCEPTION)是用来处理正常执行过程中未预料的事件

程序块的异常处理预定义的错误和自定义错误,

异常的默认处理方式:显示异常信息 并终止程序执行

三种类型的异常错误:

预定义 ( Predefined )错误

ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。

非预定义 ( Predefined )错误

即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。用户定义(User_define) 错误

程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发

异常处理的语法

  异常处理部分一般放EXCEPTION
     WHEN first_exception THEN  <code to handle first exception >
     WHEN second_exception THEN  <code to handle second exception >
     WHEN OTHERS THEN  <code to handle others exception >
  END;

异常处理可以按任意次序排列,但 OTHERS 必须放在最后.

异常的分类

Oralce中的异常分为如下三类: 预定义的ORACLE数据库异常:有异常名,有错误代码,有异常信息 非预定义的ORACLE数据库异常:无异常名有错误代码,有异常信息。 用户自定义异常:违反用户自定义的业务逻辑规则,由程序主动触发。

预定义异常

  declare
    v_empno emp.empno%type:=100;
    v_ename emp.ename%type;
    
  begin
    v_empno :=&v_empno;
    select ename into v_ename from emp where empno = v_empno;
    dbms_output.put_line(v_ename);
    
  end;

  declare
    v_empno emp.empno%type;
    v_ename emp.ename%type;
    
  begin
    v_empno :=&v_empno;
    select ename into v_ename from emp ;
    dbms_output.put_line(v_ename);
    
  end;

非预定义异常

  delete from employees where employee_id=100;

 

  delete from dept where deptno=10;

异常处理

  declare
    v_empno emp.empno%type;
    v_ename emp.ename%type;
    
  begin
    v_empno :=&v_empno;
    select ename into v_ename from emp where empno=v_empno;
    dbms_output.put_line(v_ename);
    exception
      when no_data_found then
            dbms_output.put_line('你所要查询的用户不存在');
      when too_many_rows then
           dbms_output.put_line('找到的数据过多');
          
      
      when others then
           dbms_output.put_line('程序发生错误');
    
  end;

非预定异常的处理

  --删除指定部门的记录信息,以确保该部门没有员工。
  DECLARE
     v_deptno dept.deptno%TYPE :=&deptno;--10
     e_deptno_remaining EXCEPTION;
     PRAGMA EXCEPTION_INIT(e_deptno_remaining, -2292);
     /* -2292 是违反一致性约束的错误代码 */
  BEGIN
     DELETE FROM dept WHERE deptno=v_deptno;
  EXCEPTION
     WHEN e_deptno_remaining THEN 
        DBMS_OUTPUT.PUT_LINE('违反数据完整性约束!');
     WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('发生其它错误!');
  END; 

SQLCODE、SQLERRM

  BEGIN
     INSERT INTO emp(empno, ename, hiredate, deptno)
           VALUES(2222, 'Jerry', SYSDATE, 20);
     DBMS_OUTPUT.PUT_LINE('插入数据记录成功!');
     INSERT INTO emp(empno, ename, hiredate, deptno)
           VALUES(2222, 'Jerry', SYSDATE, 20);
     DBMS_OUTPUT.PUT_LINE('插入数据记录成功!');
  EXCEPTION
     WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
  END;

输出结果

  插入数据记录成功!
  -1---ORA-00001: 违反唯一约束条件 (SCOTT.PK_EMP)

游标

在 PL/SQL 程序中,对于处理多行记录的事务经常使用游标来实现

为了处理 SQL 语句,ORACLE 必须分配一片叫上下文( context area )的区域来处理所必需的信息,其中包括要处理的行的数目,一个指向语句被分析以后的表示形式的指针以及查询的活动集(active set)。 游标是一个指向上下文的句柄( handle)或指针。通过游标,PL/SQL可以控制上下文区和处理语句时上下文区会发生些什么事情

 

 

游标的分类

显式游标

游标定义

  格式:
     CURSOR cursor_name[(parameter[, parameter]…)] IS select_statement;
     游标参数只能为输入参数,其格式为:
           parameter_name [IN] datatype [{:= | DEFAULT} expression]
      在指定数据类型时,不能使用长度约束。如NUMBER(4)、CHAR(10) 等都是错误的。

打开游标

就是执行游标所对应的SELECT 语句,将其查询结果放入工作区,并且指针指向工作区的首部,标识游标结果集合。如果游标查询语句中带有FOR UPDATE选项,OPEN 语句还将锁定数据库表中游标结果集合对应的数据行。

  格式:
  OPEN cursor_name[([parameter =>] value[, [parameter =>] value]…)];

在向游标传递参数时,可以使用与函数参数相同的传值方法,即位置表示法和名称表示法。PL/SQL 程序不能用OPEN 语句重复打开一个游标。

提取游标数据

就是检索结果集合中的数据行,放入指定的输出变量中。

  格式:
  FETCH cursor_name INTO {variable_list | record_variable };

对该记录进行处理;继续处理,直到活动集合中没有记录;

关闭游标

当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源,并使该游标的工作区变成无效,不能再使用FETCH 语句取其中数据。关闭后的游标可以使用OPEN 语句重新打开。

  CLOSE cursor_name;

游标的使用:

  --获取emp表中所有员工的信息
  declare
    cursor c_emp is select * from emp;--声明一个游标;
    o_emp emp%rowtype;
    
    begin 
      open c_emp;--打开游标
      fetch c_emp into o_emp;--提取数据
            dbms_output.put_line(o_emp.empno||'--'||o_emp.ename);
     fetch c_emp into o_emp;--提取数据
            dbms_output.put_line(o_emp.empno||'--'||o_emp.ename);
      close c_emp; --关闭游标
      
      
    end;
  ​

使用循环提取数据

  --获取emp表中所有员工的信息
  declare
    cursor c_emp is select * from emp;--声明一个游标;
    o_emp emp%rowtype;
    v_s boolean;
    
    begin 
      open c_emp;--打开游标
      if c_emp%isopen then
        loop
          fetch c_emp into o_emp;--提取数据
               
            exit when c_emp%NOTFOUND;
            dbms_output.put_line(c_emp%rowcount||'--'||o_emp.empno||'--'||o_emp.ename);
        end loop;
      end if;
      close c_emp; --关闭游标
    end;
  ​

游标属性

%FOUND 布尔型属性,当最近一次读记录时成功返回,则值为TRUE; %NOTFOUND 布尔型属性,与%FOUND相反; %ISOPEN 布尔型属性,当游标已打开时返回 TRUE; %ROWCOUNT 数字型属性,返回已从游标中读取的记录数。

 

使用for循环来提取游标数据

PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能;当进入循环时,游标FOR循环语句自动打开游标,并提取第一行游标数据,当程序处理完当前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取下一行数据供程序处理,当提取完结果集合中的所有数据行后结束循环,并自动关闭游标。格式: FOR index_variable IN cursor_name[value[, value]…] LOOP — 游标数据处理代码 END LOOP;其中: index_variable为游标FOR 循环语句隐含声明的索引变量,该变量为记录变量,其结构与游标查询语句返回的结构集合的结构相同。在程序中可以通过引用该索引记录变量元素来读取所提取的游标数据,index_variable中各元素的名称与游标查询语句选择列表中所制定的列名相同。如果在游标查询语句的选择列表中存在计算列,则必须为这些计算列指定别名后才能通过游标FOR 循环语句中的索引变量来访问这些列数据

  --获取emp表中所有员工的信息
  declare
    cursor c_emp is select * from emp;--声明一个游标;
    o_emp emp%rowtype;
    v_s boolean;
    
    begin 
      for o_emp in c_emp loop
        dbms_output.put_line(o_emp.empno||'----'||o_emp.ename);
      end loop;
        
    end;
  ​

带参的游标

  declare 
     s number :=2000;
    cursor  cc_emp(v_sal number default 800) is select * from emp where sal > v_sal;
    
    begin
      ---for oo_emp in cc_emp(1000) loop--位置传值法
      for oo_emp in cc_emp(v_sal =>s) loop--名称传值法
        dbms_output.put_line(oo_emp.ename||'----'||oo_emp.sal);
       end loop;
      
    end;

隐式游标

而对于非查询语句,如修改、删除操作,则由ORACLE 系统自动地为这些操作设置游标并创建其工作区,

这些由系统隐含创建的游标称为隐式游标,隐式游标的名字为SQL

隐式游标属性 SQL%FOUND 布尔型属性,当最近一次读记录时成功返回,则值为true; SQL%NOTFOUND 布尔型属性,与%found相反; SQL %ROWCOUNT 数字型属性, 返回已从游标中读取得记录数; SQL %ISOPEN 布尔型属性, 取值总是FALSE。SQL命令执行完毕立即关闭隐式游标。

–删除EMP 表中某部门的所有员工,如果该部门中已没有员工,则在DEPT 表中删除该部门。

  declare
         v_deptno myemp.deptno%type;
     
  begin    
         v_deptno :=&v_deptno;
         delete from myemp where deptno = v_deptno;
         if sql%notfound then
           delete from mydept where deptno = v_deptno;
           
         end if;
       
   end;

PLSQL程序单元

是数据库中命名的PL/SQL块,作为数据库对象保存在数据库中。主要有四类:过程:执行特定操作,无返回值;函数:执行复杂操作,有返回值包:逻辑上相关的过程和函数的组合体触发器:事件触发,执行相应的操作

ORACLE 提供可以把PL/SQL 程序存储在数据库中,并可以在任何地方来运行它。这样就叫存储过程或函数。

过程和函数的唯一区别是函数总向调用者返回数据,而过程则不返回数据。

存储过程的参数特性:

函数

函数将处理从程序的调用部分传递给它的信息,然后返回单个值。信息通过称为参数的特殊标识符传递给函数,然后通过RETURN语句返回。

  CREATE [OR REPLACE] FUNCTION function_name
  [(argment [ { IN| IN OUT }] type,
      argment [ { IN | OUT | IN OUT } ] type]
  RETURN return_type 
  { IS | AS }
  <类型.变量的说明> 
  BEGIN
  FUNCTION_body
  EXCEPTION
  其它语句
  END;
  ​

带参函数

  CREATE OR REPLACE Function sumSalFun(v_deptno in number,--输入参数 接收调用者传递的数据
                                       v_allsal out number--输出参数 传递给调用者的数据
                                       ) return number is
    v_sumsal number;--返回值  函数执行结束之后 返回给调用者的结果
  begin
    select sum(sal) into v_sumsal from emp where deptno = v_deptno;
  ​
    v_allsal := 200;
    return v_sumsal;
  end;

函数传参

  1. 位置表示法

  declare 
    v_result number;
    v_outpara number;
  begin 
    v_result := SUMSALFUN(20,v_outpara);--位置表示法  按照函数定义时的参数的声明位置 来在对应的位置 传递对应的参数
    
    dbms_output.put_line(v_result||'---'||v_outpara);
    
  end;

2 .名称表示法

  declare 
    v_result number;
    v_outpara number;
    vv_deptno number :=20;
  begin 
    v_result := SUMSALFUN(v_allsal=>v_outpara,v_deptno => vv_deptno);--名称表示法  按照函数定义时的参数的声明名称 给对应的名称 传递对应的参数
    
    dbms_output.put_line(v_result||'---'||v_outpara);
    
  end;

3 混合表示法

  declare 
    v_result number;
    v_outpara number;
    vv_deptno number :=20;
  begin 
    v_result := SUMSALFUN(20,v_allsal => v_outpara);--名称表示法  按照函数定义时的参数的声明名称 给对应的名称 传递对应的参数
    
    dbms_output.put_line(v_result||'---'||v_outpara);
    
  end;

存储过程

无参存储过程

  CREATE  OR  REPLACE  PROCEDURE  过程名  [(parameter,...)]
  IS
      定义变量
  Begin
      Plsql程序
  End;

执行:

在sql窗中:

  begin
    pro1();
  end;

命令窗口:

  exec pro1();

带参存储过程 输入参数

  declare
    v_empno number:=&v_empno;
    v_ename varchar2(50) :=&v_ename;
    v_sal number :=&v_sal;
    v_job varchar2(50) :=&v_job;
  begin
    --pro1(v_empno,v_ename,v_sal,v_job);--位置表示法
   -- pro1(v_empno=>v_empno,v_ename=>v_ename,v_sal=>v_sal,v_job=>v_job);--名称表示法
   pro1(v_empno,v_ename,v_sal=>v_sal,v_job=>v_job);--在混合表示法中,位置标示法必须放在前边,而且在出现名称标示法之后,不能再穿插位置标示法
  end;
  SELECT * FROM MYEMP;
  create or replace procedure pro2(v_deptno in out number,--输入输出参数
                                   v_empnum out number) is
  begin
    select count(*), sum(sal)
      into v_empnum, v_deptno
      from myemp
     where deptno = v_deptno;
  ​
  end pro2;

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111275.html原文链接:https://javaforall.net

(0)
上一篇 2021年8月23日 上午9:00
下一篇 2021年8月23日 上午10:00


相关推荐

  • 自动修复无法修复你的电脑 解决方案

    自动修复无法修复你的电脑 解决方案早上起来已开机 就看到电脑在自动修复 顿时感觉要出事 果不其然就一直这样 安全模式也经不来 后多方查找资料 不重装系统 不进 pe 完美将其解决 首先点击高级选项 疑难解答 高级选项 命令提示符 不出意外的话就进入黑框框了 bcdbootc windows lzh cn 然后回车 电脑会重启 重启之后发现提示无法加载系统按 F1 进入之后选微软键盘 进入到命令行界面 删除这个 sys 文

    2026年3月19日
    1
  • win7-64bit 下oracle11g plsql 的正确安装[通俗易懂]

    win7-64bit 下oracle11g plsql 的正确安装

    2022年2月1日
    40
  • css属性及定位操作

    字体属性文字字体font-family可以把多个字体名称作为一个“回退”系统来保存。如果浏览器不支持第一个字体,则会尝试下一个。浏览器会使用它可识别的第一个值。简单实例:body{font

    2022年3月29日
    66
  • 奔图m7160dw驱动_奔图打印机m7100dn

    奔图m7160dw驱动_奔图打印机m7100dn奔图M7100dW打印机驱动是专门为奔图旗下的M7100dW型号打印机打造的驱动程序。它能够为你解决打印机常见的无法扫描、无法识别等问题。他是连接打印机与电脑的桥梁,让你更好的操作这款的打印机。【打印机特色】1、操作便捷,乐在其中ECOSYSP2135dn外观小巧,空间适应度很高,可以更好地满足用户办公空间布置的需要。而且外形美观,放置在办公桌上能够与办公家具很好地融合在一起,营造出和谐的办公室…

    2022年8月30日
    5
  • 关于scrollHeight

    关于scrollHeightscrollHeight:这个属性就比较麻烦了,因为它们在火狐跟IE下简直差太多了..在火狐下还很好理解,它其实就是滚动条可滚动的部分还要加上boder的高度还要加上横向滚动条不可用的高度scrollHeight=滚动条可滚动的部分+border的高度+横向滚动条不可用的高度;在IE中scrollHeight确是指这个对象它所包含的对象的高度加上boder的高度和marging,如…

    2022年7月24日
    8
  • 基于ssm的个人博客系统的设计与实现(含源文件)

    基于ssm的个人博客系统的设计与实现(含源文件)欢迎添加微信互相交流学习哦!项目源码:https://gitee.com/oklongmm/biye进入二十一世纪,以Internet为核心的现代网络积水和通信技术已经得到了飞速的发展和广泛的应用,各种网络交流互动工具也应运而生。其中以论坛、博客、社区、空间最为受广大网民朋友的欢迎,也是目前为止发展的比较成熟的信息交流工具。在网络技术逐渐渗入社会生活各个层面的今天,传统的交流方式也面临着变革,而网络博客则是一个很重要的方向。基于Web技术的网络考试系统可以借助于遍布全球的Internet进行,因

    2022年7月21日
    16

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号