oracle存储过程(基础语法)

1、存储过程的定义

        存储过程(Stored Procedure )是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。存储过程是由流控制和SQL 语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。在Oracle 中,若干个有联系的过程可以组合在一起构成程序包。

2、存储过程的优缺点

优点:

  • a) 存储过程可以使得程序执行效率更高、安全性更好,因为过程建立之后 已经编译并且储存到数据库,直接写sql就需要先分析再执行因此过程效率更高,直接写sql语句会带来安全性问题,如:sql注入 。存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。:
  • b) 建立过程不会很耗系统资源,因为过程只是在调用才执行。
  • c) 存储过程可以用于降低网络流量,存储过程代码直接存储于数据库中,所以不会产生大量T-sql语句的代码流量。        
  • d) 使用存储过程能够增强对执行计划的重复使用,由此可以通过使用远程过程调用 (RPC) 处理服务器上的存储过程而提高性能。RPC 封装参数和调用服务器端过程的方式使引擎能够轻松地找到匹配的执行计划,并只需插入更新的参数值。
  • e) 可维护性高,更新存储过程通常比更改、测试以及重新部署程序集需要较少的时间和精力。
  • f) 代码精简一致,一个存储过程可以用于应用程序代码的不同位置。

缺点:

  • a) 可移植性差;换数据库的话,oracle数据库的存储过程无法迁移到mysql、db2等其他数据库,不通用;
  • b) 占用服务器端较多资源,大量存储过程并发时对数据库服务器造成很大的压力;
  • c) 对外接口受限制,只能跟oracle数据库交互,不能给其他数据库交互,也不能跟分布式数据库如hive等交互,也不能读入文件;
  • d) 后期编译报错,不能主动提示,如果用定时任务调度时,由于编译报错导致任务失败,无法监控;

3、存储过程的创建

        (在以下代码中,所有被 “[ ]” 包裹起来的均为选填项。)

        3.1、存储过程创建语句

                  create [or replace] procedure

                            存储过程名  [(参数1 类型,参数2 out 类型……)]   

            as/is

                    变量名  类型;

            begin

                 程序代码体

            end;

 注:

        运用以上语法我们可以创建一个存储过程。对于oracle的存储过程而言,只能创建(create)、删除(drop)、替换(replace)它。

         as/is这两种不同的用法,严格来说在存储过程中二者没有什么显著的差别,它们是同义词,但使用as的情况居多。值得注意的是,在创建视图的时候我们只能用as,而在声明游标的时候只能用is。

         begin与end表示PL-SQL语句块的开始和结束,所有需要执行的语句都写在此处。

                3.1.1、示例一:无参无返

                        

create or replace procedure p1
-- or replace代表创建该存储过程时,若存储名存在,则替换原存储过程,重新创建
-- 无参数列表时,不需要写()
as
begin
    dbms_output.put_line('hello');
end; 

                3.1.2、示例二:有参有返

 create or replace procedure

 p2 (name in varchar2, age int, msg out varchar2)

--参数列表中,声明变量类型时切记不能写大小,只写类型名即可,例如参数列表中的name变量的声明

--参数列表中,输入参数用in表示,输出参数用out表示,不写时默认为输入参数。

--输入参数不能携带值出去,输出参数不能携带值进来,当既想携带值进来,又想携带值出去,可以用in out

as

begin

    msg:='姓名'||name||',年龄'||age;

    --赋值时除了可以使用:=,还可以用into来实现

    --上面子句等价于select '姓名'||name||',年龄'||age into msg from dual;

end;

        3.2、执行存储过程方式

               1、 begin

                      存储过程名();

                      end;

               2、execute 存储过程名称();

               3、call 存储过程名称();

        3.3、变量与参数

                3.3.1、变量

                        create [ or replace ] procedure p3

                        as

                                [ var_1 var_type (var_size); ]

                       begin

                               -- PL-SQL blocks

                       end;

        以上是声明变量的语法,其中,var_1表示变量名,var_type表示变量的类型,var_size表示取值范围(变量大小),当我们要声明一个变量的时候,这三个元素缺一不可。

        变量类型则有多种不同的分类:标量类型、复合变量类型、参照类型、大型数据对象。 

                3.3.2、标量类型

        标量类型既包括了系统中的标准数据类型,诸如varchar、number等;亦包括了一些比较少用的类型,比如BINARY_INTEGER、boolean等。这些类型使用广泛、声明简单,是变量类型中的基础。

create or replace procedure p4
as
    v_id number(4);
    v_name varchar(20);
    v_sex varchar(10);

begin
    select id, name, sex
    into v_id, v_name, v_sex
    from aaa
    where id = '6';
end p4;

         还有一种变量类型叫做 “%TYPE” ,你可以把它看做是一种动态数据类型,它由一个已经定义了的变量调用,并返回该变量的类型。比如说:

           v_msg varchar(20);

           v_msg_back v_msg%TYPE;

            -- 在这里,v_msg 和 v_msg_back 的类型都是 varchar(20)

        与之相似的还有 “%ROWTYPE” ,顾名思义,它能保存一个表格中所有列的类型,你可以直接将它看做是一条行记录。    

           v_msg_back aaa%ROWTYPE;

           -- 在这里,aaa可以是表或视图

create or replace procedure p4

as
   v_msg_back aaa%ROWTYPE;                                                         
begin
    select *
    into v_msg_back 
    from aaa
    where id = '6';
end p4;

        3.3.3、复合变量类型

        复合记录类型:声明一种record类型的变量,该变量内含有多个标量类型的变量,随后声明该record类型的“对象”。

                type record_type_name is record (

                        var_name var_type(var_size) 

                        [, var_name var_type(var_size)]

                );

               var_record_type record_type_name;

       该语法声明了一个叫做 “record_type_name” 的记录类型,里面含有复数个变量(单个变量没有声明成记录的必要)。随后,我们声明了一个名为 “var_record_type” 的 “record_type_name” 类型的变量。

         复合表类型(关联数组):索引表(关联数组)是一种更为复杂的记录类型,尽管在声明的时候我们会用到 “is table of” ,

        但本质上来讲它更接近数组,索引表通过指定类型的索引确定其元素所在位置。下面是声明索引表的语法:

                type table_type_name is table of type_name index by index_type;

                var_table table_type_name;

        在这里,table_type_name 即是我们所声明的索引表的名字;type_name 是索引号的类型,它可以是标量类型,也可以是我们自己声明的记录类型

你可能感兴趣的:(oracle,数据库,sql)