【PL/SQL】存储过程详解

什么是存储过程

存储过程是一种命名的PL/SQL程序块,既可以没有参数也可以有若干个输入,输出参数,但是它通常没有返回值。存储过程被保存在数据库中,可以被SQL语句直接调用,只能通过EXECUT命令或者在PL/SQL程序块内部被调用。由于存储过程是已经编译好的代码,因此被调用或者引用时,执行效率非常高。

创建存储过程

示例如下:

create or replace procedure pro_name (parameter1,parameter2) is
begin 
    plsql_sentences;
[exception]
    [dowith_sentences;]
end [pro_name];

注意一下,is和as的区别:在Oracle的存储过程和函数中,其实IS和AS是同义词,没有什么区别。还有在自定义类型(TPYE)和包(PACKAGE)时,使用IS和AS也并没有什么区别。但是在创建视图(VIEW)时,只能使用AS而不能使用IS。在声明游标(CURSOR)时,只能使用IS而不能使用AS。

pro_name:存储过程名字,parameter1存储过程的参数;plsql_sentences:PL/SQL语句,它是存储过程实现的主体。dowith_sentences:异常处理语句。中括号[]是可有可无的

创建一个插入的存储过程示例:

SQL> create or replace procedure pro_insertDept is 
    begin 
          insert into dept values(77,'市场拓展部','JJ');
          commit;
          dbms_output.put_line('插入的新记录成功!');
    end pro_insertDept;
/

注意:在PL/SQL的命令窗口里面必须用“/”强制退出

调用存储过程的示例如下:

SQL> execute pro_insertDetp;     --执行的存储过程

或者如下:

SQL> set serverout on;  --这个只能在SQL PLUS里面使用,意思是在窗口里显示服务器输出信息
SQL> begin 
        pro_insertDept;
    end;
/                 --强制退出命令

注意:set serverout on;  --这个只能在SQL PLUS里面使用,意思是在窗口里显示服务器输出信息

存储过程的参数

IN模式参数:这是一种输入类型的参数,参数值有调用方传入,并且只能被存储过程读取。这种模式是最常用的,关键字in位于参数名称之后。

SQL> create or replace procedure insert_dept(
    num_deptno in number,  
    var_ename in varchar2,
    var_loc in varchar2
)  is 
    begin 
    isnert into dept values (num_deptno,var_ename,var_loc);
    commit;
    end insert_dept;
/

注意一下:参数类型的不能指定长度。

  • 指定名称传递:指在向存储过程传递参数的时需要指定参数名称(与顺序无关,但名字要一致),即参数名称在左侧,中间是赋值符号“=>”,右侧是参数值
SQL>begin 
    insert_dept(var_ename=>'采购部',var_loc=>'成都',num_deptno=>15);
    end;
/
  • 按位置传递:提供的参数数值顺序必须与存储过程中定义的参数顺序相同
SQL>begin 
    insert_dept(28,'工程部','洛阳');
    end ;
    /
  • 混合方式传递: 混合方式及时将两种结合到一起,兼顾两者的有点 

混合方法需要注意:上面两种调用方式可混合使用,但是注意,一旦某个参数有使用命名符,则后面所有的参数都得使用命名符,  否则会导致异常:“PLS-00312:一个定位相关参数没有说明其相关性

in 参数的默认值:是在声明时初始化默认值,用default关键字

SQL>create or replace procedure insert_dept(
    num_deptno in numnber,
    var_dname in varchar2 default '综合部',
    var_loc in varchar2 default '北京'
) is 
    begin 
        insert into dept values(num_deptno,var_dname,var_loc);
    end;
/

 out模式参数:输出类型参数,关键字out位于参数名称之后

创建示例:

SQL> create or replace procedure select_dept(
    num_deptno in number,
    var_dname out dept.dname%type,
    var_loc out dept.loc%type
) is begin 
    select dname,loc into var_dname,var_loc from dept 
    where deptno = num_deptno;
end select_dept;
/

注意一下:SELECT INTO 语句从一个表复制数据,然后把数据插入到另一个新表中。

(1)在PL/SQL块中调用out模式的存储过程,需要在PL/SQL块declare部分定义与存储过程中out参数类型兼容的若干变量

SQL>set serverout on
SQL> declare 
    var_dname dept.dname%type;
    var_loc dept.loc%type;
    begin 
    select _dept(99,var_dname,var_loc);
    dbms_output.putline(var_dname||'位于:'||var_loc);
end;
/

注意:select_dept(num_deptno=>99,var_dname,var_loc),这样写会报错:一个定位相关参数没有说明其相关性,必须这样写:select_dept(num_deptno=>99,var_dname=>var_dname,var_loc=>var_loc);=>左边的是参数名,要和存储过程内部一致,右侧是参数值。

(2)用exec命令执行out模式的存储过程,在SQL*Plus环境中使用variable关键字声明两个变量,用以存储out参数的返回值

例如:

SQL>variable var_dname varchar2(50);
SQL>variable var_loc varchar2(50);
SQL>exec select_dept(15,:var_dname,:var_loc);

但是用户看不到var_dname和var_loc的值,可以通过print或者select查看

 SQL>print var_dname var_loc;

 select :var_dname,:var_loc from dual;

  • 使用print命令查看
  • 使用select语句检索绑定的变量值

IN OUT 模式参数:在执行存储过程中,in参数不能被修改,只能根据被传入的指定值为存储过程提供数据,而out类型只能等待被赋值,IN out 参数可以兼顾两者的优点,在调用的时候,从外界向该类型的参数传入值,执行完之后,将结果返回值传给外界

in out 参数示例:

SQL>create or replace procedure pro_square(
    num in out number,
    flag in boolen 
) is i int :=2;
begin 
    if flag then 
            num :=power(num,i);
       else
            num :=sqrt(num);
    end if;
end;
/

调用如下:

SQL>declare var_number number;
            var_temp number;
            boo_flag boolean;
begin 
   var_temp :=3;
    var_number :=var_temp;
    boo_flag :=false;
    pro_square(var_number,boo_flag);
    if boo_flag then 
        dbms_output.put_line(var_temp||'的平方是:'var_number);
    else
        dbms_output.put_line(var_temp||'的平方根是:'var_number);
    end if;
end;
/

猜你喜欢

转载自blog.csdn.net/u012060033/article/details/85759150
今日推荐