原文地址:http://www.cnblogs.com/sin90lzc/archive/2012/08/30/2661117.html

参考文献:《Oracle完全学习手册》

1.概述

本文主要介绍PL/SQL中的有名程序块:存储过程、函数、包头/包体及触发器的使用。而这些的基础是PL/SQL无名块的编写,这在PL/SQL之基础篇 中已经讲述过了。

这四种程序块到底是什么东西呢?

存储过程可以认为它是一个无返回值的函数(排除参数返回);

函数则是一个带返回值的函数,但函数只能用于表达式中,不能像存储过程那样直接调用;

包头/包体与Java中的接口/实现类比较的话,包头就好比接口,而包体就好比实现类。

触发器则可以认为是一个事件处理函数,它能在某个事件发生时自动地执行。

2.存储过程

2.1存储过程的创建及修改

语法:

CREATE [OR REPLACE] PROCEDURE procedure_name
[(parameter_name [IN | OUT | IN OUT] datatype [{(:= | DEFAULT ) defaultvalue}] [, ...])]
{IS | AS}
BEGIN
procedure_body
END procedure_name;

语法解析:

IN:输入参数;

OUT:输出参数;

IN OUT:即可输入也可输出的参数;

datatype:参数的数据类型,此处不能带精度。

:=|DEFAULT:用于设置参数的默认值。

Example:

--注意,在声明参数类型时,不能带精度,如VARCHAR2(20)后面的(20)
CREATE OR REPLACE PROCEDURE test_procedure(name IN VARCHAR2 default 'Tim',age IN NUMBER :=20,sex IN OUT VARCHAR2,realname OUT VARCHAR2)
ISrn VARCHAR2(10) default 'Tim Leung';
BEGINIF name='Tim' THENrealname:=rn;END IF;IF sex='1' THENsex:='男';ELSEsex:='女';END IF;DBMS_OUTPUT.PUT_LINE(name || ' age:'||age||' sex:'||sex||' realname:'||realname);
END test_procedure;

2.2 过程的调用

declare result_sex varchar(3):='1';result_rn varchar(10) default null;
begintest_procedure('Tim',sex => result_sex,age => 20,realname => result_rn);--可以使用符号=>来传参DBMS_OUTPUT.PUT_LINE('sex:'||result_sex);DBMS_OUTPUT.PUT_LINE('realname:'||result_rn);
end;/*运行结果:
Tim age:20 sex:男 realname:Tim Leung
sex:男
realname:Tim Leung
*/

2.3 删除过程

DROP PROCEDURE test_procedure;

3.函数

过程用来完成一项任务,可能不返回值,也可能返回多个值,过程的调用是一条PL/SQL语句;函数包含RETURN子句,用来进行数据操作,并返回一个单独的函数值,函数的调用只能在一个表达式中

3.1创建及修改函数

语法:

CREATE [OR REPLACE] FUNCTION function_name
[(parameter1 {IN | OUT | IN OUT} datatype] [,...])]
RETURN datatype
{ IS | AS }
BEGIN
function_body
END function_name;

Example:

CREATE OR REPLACE FUNCTION test_function(name IN VARCHAR2 default 'Tim',age IN NUMBER :=20,sex IN OUT VARCHAR2,realname OUT VARCHAR2)
RETURN VARCHAR2
ISrn VARCHAR2(10) default 'Tim Leung';
BEGINIF name='Tim' THENrealname:=rn;END IF;IF sex='1' THENsex:='男';ELSEsex:='女';END IF;RETURN (name || ' age:'||age||' sex:'||sex||' realname:'||realname);
END test_function;

3.2调用函数

declare result_sex varchar(3):='1';result_rn varchar(10) default null;
begin--可以使用符号=>来传参DBMS_OUTPUT.PUT_LINE(test_function('Tim',sex => result_sex,age => 20,realname => result_rn));
end;/*运行结果:
Tim age:20 sex:男 realname:Tim Leung
*/

4.包头/包体

4.1包头创建及修改

语法:

CREATE [OR REPLACE] PACKAGE package_name
{ IS | AS }
package_specification  --存储过程,函数,变量声明部分
END package_name;

Example:

CREATE OR REPLACE PACKAGE test_package
IS
v_name VARCHAR2(20);--声明公有变量
PROCEDURE getName(id NUMBER);--声明过程getName
PROCEDURE getName(p_name VARCHAR2);--声明重载过程getName
FUNCTION getAge RETURN NUMBER;--声明函数getAge
END test_package;

4.2包体的创建及修改

语法:

--包体名必须与包头名一致!
CREATE [OR REPLACE] PACKAGE BODY package_name
{ IS | AS}package_implement  --存储过程,函数实现部分BEGINpackage_init  --包初始化部分,在包被第一次调用时执行END;
--注意!!!包体不能有END;子句

Example:

CREATE OR REPLACE PACKAGE BODY test_package IS --包体名与包头名要一致/*创建私有过程output,以供其他过程或函数调用,必须在其他过程或函数调用前创建*/PROCEDURE output(output_str VARCHAR2) ISBEGINDBMS_OUTPUT.PUT_LINE(output_str);END output;/*创建公有过程getName*/PROCEDURE getName(id NUMBER) ISBEGINoutput('do getName('||id||')');END getName;/*重载过程getName,重载的意思即有相同的过程名或函数名,相同的返回类型,不同的参数列表!*/PROCEDURE getNAME(p_name VARCHAR2) ISBEGINoutput('do getNAME('||p_name|| ')!');END getNAME;/*创建函数getAge*/FUNCTION getAge RETURN NUMBER ISBEGINRETURN 20;END getAge;/*包的初始化块,在包被第一次调用时执行。初始化块只能在包体的末尾编写*/BEGINv_name:='Tim';END;--注意!!包体不能有END;子句

4.3 包的调用

declare
beginDBMS_OUTPUT.PUT_LINE(test_package.v_name);test_package.getName(10);test_package.getName('Tim');DBMS_OUTPUT.PUT_LINE('getAge:' || test_package.getAge);
end;/*运行结果:
Tim
do getName(10)
do getNAME(Tim)!
getAge:20
*/

5.触发器

5.1触发器的分类

触发器主要有DML触发器、替代触发器、系统触发器及DDL触发器几种类型。

  • DML触发器
    DML触发器可以处理INSERT、UPDATE和DELETE事件。DML触发器可以在语句级或行级操作上被触发,语句级触发器对于每一个SQL语句只触发一次,行级触发器对SQL语句受影响的表中的每一行都触发一次
  • 替代触发器
    替代触发器主要针对处理视图的DML操作事件(INSERT、UPDATE和DELETE)。替代触发器只能在行级操作上被触发,不能在语句级上被触发。

  • 系统触发器
    分为数据库级(Database)和模式级(Schema)两种。数据库级触发器的触发事件对于所有用户都有效,模式级触发器仅被指定模式的用户触发。系统触发器支持的触发事件有:LOGON、LOGOFF、SERVERERROR、STARTUP和SHUTDOWN。
  • DDL触发器
    即由DDL语句(CREATE、ALTER或DROP等)触发的触发器。

5.2创建及修改触发器

语法:

CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF} trigger_event
ON event_target
[FOR EACH ROW]
[WHEN condition]
BEGINtrigger_body
END trigger_name;

语法解析:

INSTEAD OF:仅用于替代触发器,即event_target必须为视图,而且必须带FOR EACH ROW子句

trigger_event:触发的事件。可以是DML事件(INSERT、UPDATE、DELETE、INSERT OR UPDATE、UPDATE OF column_name),系统事件(STARTUP、SHUTDOWN等)。

event_target:即指trigger_event事件是发生在哪个对象上的。如DML事件,那么event_target应该是表名或视图名,如果是系统事件,那么event_target就应该是DATABASE或SCHEMA

FOR EACH ROW:如果带此子句,即表示该触发器是行级触发器,如果省略,则是语句级触发器。

WHEN condition :用于限制行级触发器,只有满足condition条件,才会触发触发器。

Example:

CREATE OR REPLACE TRIGGER test_trigger
AFTER INSERT OR UPDATE OF sal OR DELETE
ON emp
FOR EACH ROW
BEGINCASEWHEN INSERTING THEN  --当事件为INSERT时,INSERTING为TRUE/*:NEW关键字可以获取新记录的数据,它只能用于行级触发器*/DBMS_OUTPUT.PUT_LINE('INSERT INTO EMP VALUES('||:NEW.empno||','||:NEW.ename||','||:NEW.job||','||:NEW.mgr||','||:NEW.hiredate||','||:NEW.sal||','||:NEW.comm||','||:NEW.deptno||')');WHEN UPDATING THEN  --当事件为UPDATE时,UPDATING为TRUEDBMS_OUTPUT.PUT_LINE('UPDATING emp which empno='||:OLD.empno||'to sal:'||:NEW.sal);--:OLD关键字可以获取旧记录的数据,它只能用于行级触发器WHEN DELETING THEN  --当事件为DELETE时,DELETING为TRUEDBMS_OUTPUT.PUT_LINE('DELETING emp which empno='||:OLD.empno);--:OLD关键字可以获取旧记录的数据,它只能用于行级触发器ELSENULL;END CASE;
EXCEPTIONWHEN DUP_VAL_ON_INDEX THENNULL;WHEN OTHERS THENRAISE_APPLICATION_ERROR(SQLCODE,SQLERRM);
END test_trigger;

执行DML操作触发上面的触发器,效果如下:

5.3修改触发器的状态

触发器有ENABLED和DISABLED两种状态。

修改某个触发器的状态可以执行下面的SQL:

ALTER TRIGGER trigger_name ENABLE | DISABLE;

使某个表上的所有触发器有效或无效:

ALTER TABLE table_name {ENABLE | DISABLE} ALL TRIGGERS;

5.4删除触发器

DROP TRIGGER trigger_name;

转载于:https://www.cnblogs.com/m-xy/p/3276838.html

PL/SQL之高级篇相关推荐

  1. 【pl/sql番外篇】 存储过程 游标

    SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的返回值被赋予INTO子句中的变量,变量的声明是在DELCARE中.SELECT     ...

  2. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)...

    [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) 原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之 ...

  3. ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

    [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日之功) 继上四篇:ORACLE PL/SQL编程之八:把触发器说透                ORAC ...

  4. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)

    [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日之功) 继上四篇:ORACLE PL/SQL编程之八:把触发器说透                ORAC ...

  5. PL/SQL高级编程

    PL/SQL高级编程 实验目的: 1.掌握PL/SQL的数据结构和编程结构,掌握应用PL/SQL编写简单程序的方法 2.理解存储过程的概念,掌握编写存储过程的方法 3.理解函数的概念,掌握编写存储过程 ...

  6. SQL注入漏洞全接触--高级篇

    2019独角兽企业重金招聘Python工程师标准>>> 看完入门篇和进阶篇后,稍加练习,破解一般的网站是没问题了.但如果碰到表名列名猜不到,或程序作者过滤了一些特殊字符,怎么提高注入 ...

  7. Oracle PL/SQL中异常高级特性

    在OraclePL/SQL语句块中exception的异常处理部分是非常重要的组成部分,它决定了在PL/SQL语句块内部可执行部分在发生异常错误时,程序是友好地提示:程序遇到某些错误而无法执行,还是抛 ...

  8. pl/sql 免安装客户端月经贴一篇

    pl/sql直接安装上是不能连接到oracle的他需要媒介,即oracle提供的文件包.有两种方法获取, 一.到官网下载instantclient-basic-win32XX包,链接如下: http: ...

  9. oracle raise_application_error mysql_Oracle PL/SQL中异常高级特性

    在OraclePL/SQL语句块中exception的异常处理部分是非常重要的组成部分,它决定了在PL/SQL语句块内部可执行部分在发生异常错误时,程序是友好地提示:程序遇到某些错误而无法执行,还是抛 ...

最新文章

  1. Matlab中寻找二值图像最大联通域的算法
  2. linux openssl libcurl库 交叉编译
  3. Bash shell的内建命令:type
  4. impala元数据放到mysql_impala系列: 同步Hive元数据和收集统计信息
  5. Tomcat JVM 初始化加大内存
  6. 单元测试java小白_一位Java应届毕业生工作7个月后的小结
  7. 转 SPI和API的区别
  8. 六种电平转换的优缺点
  9. 8有价值的电子商务网站设计要点
  10. 如何配置 SSH 免密码登录
  11. Tangents UVA - 10674 (求两个圆公切线的切点)
  12. No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK .
  13. Nginx报504 gateway timeout错误的解决方法
  14. Android Studio 中 为模拟器添加图片和图片路径(图文级教程)
  15. 秦九邵算法计算多项式(C语言实现)
  16. mysql8 内存设置_高性能的MySQL(8)优化服务器配置一内存
  17. VirtualBox 5.1.24神更新
  18. 如何保证企业服务器安全-MCK主机加固解决方案
  19. 用“找回你”,查找手机号的前身都被注册过些什么……
  20. Windows Server 2016远程桌面服务配置方法

热门文章

  1. 对口高考计算机vf试题,计算机对口升学模拟答案.doc
  2. 隐层元素闪一下_太阳一直依靠什么元素在燃烧,地球上的重元素又是怎么来的?...
  3. 查看环境列表_Xfce 4.14桌面环境正式发布,想要图形界面又想节省内存?就它了...
  4. c++ socket学习(1.6)
  5. leetcode 40. 组合总和 II 思考分析
  6. css菜单下拉菜单_在CSS中创建下拉菜单
  7. android 服务端 漏洞,安卓漏洞 CVE 2017-13287 复现详解-
  8. 如何在电脑上截屏_如何在电脑上截图?教你6种常用的截图方法,总有你不知道的...
  9. 80. 删除排序数组中的重复项 II golang
  10. int * p =NULL;和*p =NULL的区别a和a的区别