• 五、Oracle SQL(存储过程)


    7. 存储过程

    7.1 简介

    7.1.1 定义

    所谓存储过程,就是一段存储在数据库中执行某块业务功能的程序模块。
    它是由一段或者多段的PL/SQL代码块或者SQL语句组成的一系列代码块。

    7.1.2 结构分析

    create [or replace] procedure 过程名
    ( p1 in|out datatype,
      p2 in|out datatype,
      ...
      pn in|out datatype
    
    ) is/as
    
        ....--声明部分
    
        begin
    
        ....--过程体
    
        end;
    
    PS:标紫色的语句去掉后就是无参形式的存储过程
    PS:在调用存储过程时,=>前面的变量为存储过程的形参且必须于存储过程中定义的一致,而=>后的参数为实际参数。当然也不可以不定义变量保存实参。
      例:myDemo04(name=>name,age=>18)这种为正确的形参赋值,不能直接写 myDemo04(name=>name,18),这是错误的写法;
    

    create [or replace] :如果存储过程已经存在则覆盖替代原有的过程。

    procedure :创建存储过程的命令。

    in|out

    • 存储过程具有入参和出参两种参数选择,in表示的是入参,out表示的是出参。
    • 在使用过程的时候,入参必须得有对应的变量传入,出参得有对应的变量接收。

    datatype :表示出入参变量对应的数据类型。

    is/as :后面跟着的是过程当中使用到的声明变量。

    begin...end :中间编写的就是存储过程的具体操作。

    7.1.3 调用分析

    假设现在有一个无参存储过程myDemo01(有参存过同理)需要调用
    
    --方式1:声明declare关键字调用
    declare
    begin
      myDemo01;
    end;
    
    --方式2:不声明declare关键字调用
    begin
      myDemo01; --在此处也可使用myDemo01();完成存储过程的调用
    end;
    
    --方式3:使用call存储过程名完成调用,注意括号不能少
    call myDemo01();
    
    
    --方式4:在command命令窗口执行
    SQL> set serveroutput on
    SQL> exec mydemo01
    
    
    PS:1、在调用存储过程时,如果存储过程没有参数,调用时括号()可以不带。
    
        2、存储过程带参数需要注意参数的传递参数时的一致性,按顺序依次传递。
    

    7.2 例子

    7.2.1 编写存储过程

    --创建一个存储过程计算学生某一个课程中成绩在班中的排名,使用存储过程进行计算,返回对应的排名
    CREATE OR REPLACE PROCEDURE sp_score_pm (
            --学号
            p_in_stuid IN VARCHAR2,
            --课程ID
            p_in_courseid IN VARCHAR2,
            --排名
            p_out_pm out NUMBER
        ) IS
        --过程中使用的声明变量:成绩
        ls_score NUMBER := 0 ;
        --过程中使用的声明变量:成绩比该学生高的人数
        ls_pm NUMBER := 0 ;
    BEGIN
    
        --1.获取该学生的成绩
        SELECT
            T .score INTO ls_score
        FROM
            score T
        WHERE
            T .stuid = p_in_stuid
        AND T .courseid = p_in_courseid ;
    
        --2.获取成绩比该学生高的人数
        SELECT
            COUNT (*) INTO ls_pm
        FROM
            score T
        WHERE
            T .courseid = p_in_courseid
        AND T .score > ls_score ;
    
        --3.得到该学生的成绩排名
        p_out_pm := ls_pm + 1 ;
    
    EXCEPTION
        WHEN no_data_found THEN
            dbms_output.put_line (
                '该学生的课程:' || p_in_courseid || '的成绩在成绩表中找不到'
            ) ;
    END ;
    

    7.2.2 调用存储过程

    --在SQL窗口执行编译上面的代码,编译成功后,我们就可以调用存储过程来获取学生对应的课程成绩排名了,
    --存储过程需要出入参赋值,因此我们可以通过PL/SQL语句块进行测试,代码如下:
    declare
    ls_pm number;--排名
    begin
      --学号SC201801001的学生成绩排名
      sp_score_pm('SC201801001','R20180101',ls_pm);
      dbms_output.put_line('学号:SC201801001,课程号:R20180101 的成绩排名是:'||ls_pm);
      sp_score_pm('SC201801001','R20180102',ls_pm);
      dbms_output.put_line('学号:SC201801001,课程号:R20180102 的成绩排名是:'||ls_pm);
      --学号SC201801002的学生成绩排名
      sp_score_pm('SC201801002','R20180101',ls_pm);
      dbms_output.put_line('学号:SC201801002,课程号:R20180101 的成绩排名是:'||ls_pm);
      sp_score_pm('SC201801002','R20180102',ls_pm);
      dbms_output.put_line('学号:SC201801002,课程号:R20180102 的成绩排名是:'||ls_pm);
    end;
    
    PS:本例中通过||符号达到连接字符串的功能
    

    7.3 使用存储过程的好处

    7.3.1 降低总体开发成本。

    存储过程把实际执行的业务逻辑PL/SQL块和多条SQL语句封装到存储过程当中,其它开发者只需要调用写好的过程,获取想要的结果,不需要重新理解业务。把业务抽取出来由专门的人来编写。

    7.3.2 增加数据的独立性。

    它的作用和视图的作用类似,假如表的基础数据发生变化,我们只需要修改过程当中的代码,而不需要修改调用程序。使得用户程序不需要直接面对基础数据进行编写代码。使得代码内聚程度更高,耦合度更低。

    7.3.3 提高性能。

    实际开发过程中,一个业务模块功能的开发可能需要用到多个SQL语句,多个PL/SQL程序块才能解决问题。把它编写进过程,Oracle只需要一次编译,以后随时可以调用。如果不使用过程,直接把许多SQL语句写进程序当中,需要多次编译,而且需要多次连接数据库,大大的降低了性能。


    转载自:有梦想的肥宅

  • 相关阅读:
    MySQL事物原理及事务隔离级别
    sql中in和exists的原理及使用场景。
    PHP实现多继承
    磁盘inode节点被占满的解决方法
    使用uwsgi和gunicorn部署Django项目
    python自学经验,每天进步一点点
    msyql 5.7安装遇到的坑
    shell 三剑客
    nginx 配置
    websphere 新建profile
  • 原文地址:https://www.cnblogs.com/cy-8593/p/12559320.html
Copyright © 2020-2023  润新知