Oracle存储过程,触发器,函数

什么是存储过程和函数?

    存储过程和函数是为了执行一定任务而组合在一起的一种命名的PL/SQL块,编译后作为一种数据库对象存储在数据字典中,可以被用户多次调用来完成某种功能。

什么是触发器?

     触发器是在触发一定事件的时候隐式执行的一段PL/SQL块,编译后作为一种数据库对象存储在数据字典中,只能被事件触发。 

存储过程语法:


 创建存储 过程 ,需 要有CREATE PROCEDURE或CREATE ANY 
PROCEDURE的系统权限。 
 创建一个存储过程的基本语句如下: 
CREATE [OR REPLACE] PROCEDURE 存储过程名[(参数
[IN|OUT|IN OUT] 数据类型...)] 
{AS|IS} 
[说明部分] 
BEGIN 
可执行部分 
[EXCEPTION 错误处理部分] 
END [过程名]; 
储存过程储存过程- -说明说明  
可选关键字OR REPLACE 表示如果存储过程已经存在,则用新的存储
过程覆盖,通常用于存储过程的重建。 
参数部分用于定义多个参数(如果没有参数,就可以省略)。参数有三种
形式:IN、OUT和IN OUT。如果没有指明参数的形式,则默认为IN。 
关键字AS也可以写成IS,后跟过程的说明部分,可以在此定义过程的局
部变量。 
编写好的存储过程必须要进行编译,生成编译代码,原代码和编译代码
在编译过程中都会被存入数据库。编译成功的存储过程就可以在Oracle
环境下进行调用了。  

存储过程示例:

1.    简单存储过程的创建执行和删除:

create or replace procedure sayhello 
as
begin
      dbms_output.put_line('Hello FZW'); //这就是一个输出语句
end;

存储过程的执行:

begin
  sayhello(); //经试验必须要加上括号和分号
end;

删除存储过程

drop procedure sayhello(存储过程名); 

2.利用存储过程进行计算: 计算输出一个count所花费的时间

create or replace procedure testtime
is
 t_start number;
 t_end number;
 sam number;
 use_time number;
begin
  t_start:=dbms_utility.get_time;  //注:赋值的是时候是:=
  select count(*) into sam from mdm_test_db1;
  t_end:=dbms_utility.get_time;
  use_time:=t_end-t_start;
  dbms_output.put_line('花费时间:'||use_time||'s');  //此处的||就是连接符
  end;

3.给存储过程中的变量赋值

create or replace procedure test_parameter(num in number)
is
begin 
  dbms_output.put_line('The input number is:'||num);
end;

执行:

declare

n number;                                                     

begin

 n:=5;

test_parameter(num=>n);

end;

或者:  =>后面的参数必须是实际传入的参数,当然可以不定义变量存参数

 begin
     test_parameter(num=>9);
     end;

4. 插入


  CREATE OR REPLACE  procedure proc_test_Insert_Single(e_no in number,e_name in varchar ,s in varchar,d in               varchar)
       as
       begin
              insert into emp (emp_id,emp_name,salary,birthday) values (e_no,e_name,s,d);
       end;
       调用:
       DECLARE
       i NUMBER;
       n varchar(5);
       s varchar(11);
      d varchar(10);
       BEGIN
             i:=10;
             n := 'text11';
             s:='3998';
             d:='1998-02-02';
             PROc_TEST_Insert_single(e_no => i,e_name=>n,s=>s,d=>d);
       END;
       注:调用存储过程声明varchar时,必须限定长度,即斜体的部分不能少。同时如果给变量赋值时大于限定的长度了,则会提示ORA-06502: PL/SQL: 数字或值错误 :  字符串缓冲区太小。

============================================================

存储函数:

函数(function)为一命名的存储程序,可带参数,并返回一计算值。函数和过程的结构类似,但必须有一个return子句,用于返回函数值。函数说明要指定函数名、结果值的类型,以及参数类型等。

存储函数语法:

create[or replace] functiion 函数名(参数列表) 

return函数值类型

as

    PLSQL子程序体;

 

例子:

查询员工年收入

--查询某个员工的年收入
create or replace function queryempincome(eno in number)
return number
as
  --月薪和奖金
  psal   emp.sal%type;
  pcomm  emp.comm%type;
begin
  select sal,comm into psal,pcomm from emp where empno=eno;
  --返回年收入
  return psal*12+nvl(pcomm,0);
end;
/

===================

用存储过程实现:

create or replace procedure queryEmpInfo(eno in number,
                                         pname out varchar2,
                                         psal  out number,
                                         pjob  out varchar2)
as 
begin
  select ename,sal,empjob into pname,psal,pjob from emp where empno=eno;
end;

存储过程和存储函数的区别:

一般来讲,函数和过程的区别在与函数是有返回值,而过程没有,但过程和函数都可以通过out来指定一个或多个输出参数,我们可以利用out在函数和过程中实现返回多个值。

如果有一个返回值,我们就用函数,没有返回值我们就用过程,过程也可以包含return语句,但不同的是这个return不能有返回值,此return用于直接跳至程序末尾,结束控制循环。

触发器:

触发器是一种特殊的PL/SQL块,在特定事件发生时被触发被触发执行. 
触发器的触发事件分可为3类,分别是DML事件、DDL事件和数据库事件。 
每类事件包含若干个事件,如下表所示。数据库的事件是具体的,在创建触发器时要指明触发的事件。 
事件种类 关 键 字 含    义 
DML事件(3种) 级别(2种)  INSERT 在表或视图中插入数据时触发 
                                          UPDATE 修改表或视图中的数据时触发 
                                          DELETE 在删除表或视图中的数据时触发 
DDL事件(3种)                    CREATE 在创建新对象时触发

                                           ALTER 修改数据库或数据库对象时触发 
                                           DROP 删除对象时触发 
数据库事件(5种) 
                                             STARTUP 数据打开时触发 
                                             SHUTDOWN 在使用NORMAL或IMMEDIATE选项关闭数据库时触发 
                                              LOGON 当用户连接到数据库并建立会话时触发 
                                               LOGOFF 当一个会话从数据库中断开时触发 
                                              SERVERERROR 发生服务器错误时触发 

触发器的类型可划分为4种:数据操纵语言数据操纵语言(DML)触发器触发器、替代
(INSTEAD OF)触发器、数据定义语言(DDL)触发器和数据库事件触发器。 
 
 
种  类                         简  称                   作    用 
数据操纵语言触发器  DML触发器       创建在表上,由DML事件引发的触发器 
替代触发器      INSTEAD OF触发器    创建在视图上,用来替换对视图进行的插入、删除和修改操作 
数据定义语言触发器  DDL触发器         定义在模式上,触发事件是数据库对象的创建和修改 
数据库事件触发器 —                              定义在整个数据库或模式上,触发事件是数据库事件 

============================================

触发器示例:

1.要求更新后的年龄不能小于更新前的年龄

create or replace trigger checkage
  before  update
  on MYTEST   
  for each row
declare
  -- 如果要声明本地变量,可以在这里书写
begin

  --   if  增加之后的年龄小于增加之前的年龄  then
   --    raise_applicatioin_error(-2001,'错误信息')
  --*/
  --下边的:new  和  :old两个关键字可以根据表中字段来获取表中操作前后的实际数据,以此来判断操作前后数据发生变化的情况。
  if:new.age<:old.age then
  raise_application_error(-20002,'增加之后年龄不能小于增加之前的年龄.增前:'||:old.age||'||增后:'||:new.age);
  end if;
end checkage;

测试:


 Oracle存储过程,触发器,函数_第1张图片

把年龄大于原来的值在此进行测试发现,测试成功。

示例二:

要求不允许在非工作时间修改数据。

create or replace trigger security
  before insert
  on  mdm_test_db2
  for each row
declare
  -- local variables here
begin
   if to_char(sysdate,'day') in ('星期天','星期五','星期六') or to_number(to_char(sysdate,'hh24')) not  between 9 and 17 then
    raise_application_error(20001,'禁止在非工作时间修改数据');
    end if;
end security;

 

–security是为触发器起的别名 
before insert on MYTEST 意思就是在插入MYTEST表之前进行执行触发器操作 
BEGIN 后边开始进行书写触发器的操作。 
raise_application_error(20001,’禁止在非工作时间插入新员工’);这是抛出一个例外的书写格式。记住就行 
end if; if之后如果后边没有没有内容,切记写上 
end security; 这是最后的结束标记他不是固定的而是根据别名来生成的,然后通过按年F8按键进行编译如果没有错误则说明编译成功,进入监视数据库的状态。
 

测试

Oracle存储过程,触发器,函数_第2张图片

测试成功。


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(数据库,Øracle)