Oracle PL/SQL

一. PL/SQL: 过程化语言,是专门为Oracle开发的一门语言。

  1. PL/SQL块:3部分组成

    1.1 声明部分(declare):可以省略

     主要是用来定义一些变量,游标,类型等等。

    1.2 执行部分(begin):不能省略

     主要用来编写具体的业务逻辑执行的代码。

    1.3 异常处理(exception):可以省略

     主要用来捕获程序中出现的异常情况,并进行处理

    语法:

      [declare

       变量声明:

       类型声明:

       游标定义: ]

      begin

       编写业务逻辑的代码执行:

      [exception

       异常处理的代码 ]

      end;

  注意:在PL/SQL块中每一条语句之后必须要使用";"结尾

  2. 数据类型

    2.1 简单的数据类型

    (1)数值型:number,int

    (2)字符串类型:char,varchar2,long

    (3)时间类型:date,timestamp

    (4)布尔类型:boolean:true/false

    2.2 特殊数据类型

    (1)%type:定义的变量的数据类型和某一张表中的指定字段的数据类型保持一致

      语法:变量名 表名.字段名%type;

    (2)record:记录类型,可以将多个变量封装成一个整体,在后续的使用过程中直接使用该记录

      使用步骤:1. 定义一个记录类型(自定义数据类型)

             type 记录名 is record(

              变量名  数据类型,

              变量名  数据类型,

              ......

             );

           2. 声明一个记录类型的变量

            变量名  记录名

           3. 在访问记录类型里面的变量的时候需要使用记录类型定义的变量来访问

            记录名.变量名

      例子: declare

           type emp_datas is record(

            id emp.eno%type,

            name emp.ename%type,

            sal emp.sal%type

           );

           edata emp_datas;

          begin

           select eno,ename,sal into edata from emp where eno = '01';

           dbms_output.put_line(edata.id,edata.name,edata.sal);

          end

    (3)%rowtype:行类型,定义该类型的变量就相当于拥有该表中所有列的变量

      语法:变量名 表名%rowtype;

  3. 变量的定义

    在内存中开辟存储空间来保存数据

    语法:变量名 数据类型[长度] [:=初始值]

    例子:a int := 10;

    注意:定义变量的时候变量名必须符合规范,在赋值的时候要使用":=",变量的数据类型是字符串类型的时候需要写长度

  4. 常量的定义

    语法:常量名 constant 数据类型[长度] := 常量值

    例子:a constant int := 10;

    注意:常量定义时必须赋值

二. PL/SQL中的流程控制语句

  程序结构有3种

  1. 顺序结构:从上往下依次执行

  2. 分支结构:根据条件结果选择不同的执行内容

  (1)if:单分支语句

    语法:if 条件判断 then

        条件成立时执行的代码

       end if;

  (2)if ...... else ......:双分支语句

    语法:if 条件判断 then 

        条件成立时执行的代码

       else

        条件不成立时执行的代码

       end if;

  (3)if ...... elsif ...... else:多分支语句

    语法:if 条件判断1 then 

        条件1成立时执行的代码

       elsif 条件判断2 then

        条件2成立时执行的代码

       ...

       else

        条件不成立时执行的代码

       end if;

  (4)case ... when语句:进行等值匹配

    语法:case 变量

        when 值1 then

          当变量的值等于值1时执行的代码

        when 值2 then

          当变量的值等于值2时执行的代码

        ....

        else

          以上的值都不等时执行的代码

        end case;

  3. 循环结构:在满足指定的条件的前提下,重复执行某一段代码

  (1)loop:

    语法:loop

        循环体

        exit when 循环条件;

        循环体

        end loop;

    执行顺序:先执行循环体,然后判断循环条件,如果条件不成立则继续执行循环

         如果条件成立则退出循环

  (2)while:

    语法:while 循环条件 loop

        循环体

       end loop;

    执行顺序:判断循环条件,如果条件成立则执行循环体,如果条件不成立则退出循环

  (3)for:

    语法:for 循环变量 in [reverse] 下限..上限|游标名 loop

        循环体

       end loop;

    注意:reverse:代表反转,相当于从上限到下限

三. 游标

  在SQL语句执行的时候,系统会自动分配一块内存空间,用来保存sql语句执行所影响的数据,这一块空间就可以看作游标

  游标分类

  1. 显示游标:主要用来操作查询语句的查询结果(结果集)

   特点:游标必须由用户自己定义

   定义游标的语法:

    cursor 游标名[(参数)] is 

    查询语句;

   注意:游标在declare中定义

   操作步骤:(1)定义游标(2)打开游标 语法:open 游标名 [(参数值)];(3)读取游标 语法:fetch 游标名 into 变量;(4)关闭游标

   例子:

    declare

     cursor cur_emp is

      select * from emp where deptno = 30;

     row_emp emp%rowtype;

    begin

     open cur_emp;

     loop

      fetch cur_emp into row_emp;

      exit when cur_emp%notfound;

      dbms_output.put_line(cur_emp.ename);

     end loop;

     close cur_emp;

    end;

   使用for循环来操作游标:

    语法:fro 变量名 in 游标名[(参数值)] loop

        循环体

       end loop;

    例子:

     declare

      cursor cur_emp is

       select * from emp where deptno = 30;

     begin

      for row_emp in cur_emp loop

       dbms_output.put_line(cur_emp.ename);

      end loop;

     end;

   游标的属性:

    (1)%notfound:返回布尔类型的值,如果游标没有读取到数据则返回true

    (2)%found:返回布尔类型的值,如果游标有读取到数据则返回true

    (3)%rowcount:返回数字类型的值,返回游标影响的行数

    (4)%isopen:返回布尔类型的值,如果游标打开返回true,没打开返回false

  2. 隐式游标:主要用来操作DML(insert,update,delete等待)语句,也可以操作查询的结果集

   在Oracle数据库中,每次执行SQL语句系统都会自动为该条语句创建一个游标,这一类游标就叫隐式游标

   在Oracle数据库中所有的隐式游标统一名称——sql

 

   使用隐式游标配合for 循环实现查询操作

   语法: for 变量名 in (查询语句) loop

        循环体

      end loop;

   例子:

    begin

     for row_emp in (select * from emp where deptno = 30;) loop

      dbms_output.put_line(cur_emp.ename);

     end loop;

    end;

  3. 引用游标(ref游标):在存储过程中如果要返回一个结果集则需要使用引用游标

   暂时不写

四. 异常处理

  语法:exception

     when 异常名称1 then

      异常处理代码

     when 异常名称2 then

      异常处理代码

  异常的分类:

  (1)系统的预定义异常:数据库中已经定义好的异常,我们可以直接拿过来使用

      常见的异常有:

      zero_divide:除数为0异常

      no_date_found:使用select...into语句的时候没有查询到数据

      too_many_rows:使用select..into语句的时候查询到多行数据

      cursor_already_open:试图打开一个已经打开的游标

      invalid_cursor:一个非法游标操作,试图关闭一个没有打开的游标

  (2)用户自定义异常

    (2.1)错误编号异常:将数据库中出现的一些异常编号,和一个异常变量进行绑定,在后续进行捕获

                就可以直接使用异常变量来处理对应异常编号的异常

      步骤:

        1. 定义异常变量

          变量名 exception;

        2. 将异常变量名和错误编号进行绑定

          pragma exception_init(异常变量名,错误编号);

        3. 使用异常变量名来捕获异常

      例子:

        declare

         exc exception;

         pragma exception_init(exc,-00001);

        begin

         insert into dept(deptno) values(10);

        exception

         when exc then

          dbms_output.put_line('主键不能重复!');

        end;

      注意:错误编号异常,其实也算是系统异常,异常的引发是由系统来完成的

    (2.2)业务逻辑异常:是由用户根据自己的业务逻辑需要定义的异常,并且在规定的时间内由用户引发

       步骤:

        1. 定义异常变量

          变量名 exception;

        2. 在逻辑需要的时候进行引发异常

          raise 异常变量名

        3. 用户引发的异常必须要使用exception进行处理

      例子:     

        declare
         dname_null_exception exception;
         r_dept dept%rowtype;
        begin
         r_dept.deptno:=21;
         r_dept.loc:='深圳';
         insert into dept values(r_dept.deptno,r_dept.dname,r_dept.loc);
         if r_dept.dname is null then
          raise dname_null_exception;
         end if;
         commit;
        exception
         when dname_null_exception then
          dbms_output.put_line('部门名称不能为空');
         rollback;
        end;

posted @   Luo_YB  阅读(89)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示