pl/sql 笔记之存储过程、函数、包、触发器(下)

时间:2022-04-03 00:04:19
一、存储过程、存储函数
 
1、What's This?
①、ORACLE 提供可以把 PL/SQL 程序存储在数据库中,并可以在任何地方来运行它。这样就叫存储过程或函数。
②、存储过程、存储函数的唯一区别是存储函数有返回值,而存储过程没有返回值。
 
2、创建存储函数
eg、根据部门号返回部门总工资
CREATE OR REPLACE FUNCTION get_salary(
dep_id IN employees.department_id%TYPE DEFAULT 10, -- 输入参数, 可以设置默认值
emp_count OUT NUMBER -- 输出参数
)
RETURN NUMBER -- 返回值类型
IS
v_sum NUMBER; BEGIN SELECT sum(salary), COUNT(*) INTO v_sum, emp_count
FROM employees
WHERE department_id = dep_id;
RETURN v_sum; -- 返回值
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No data found');
WHEN OTHERS THEN
dbms_output.put_line('Other Exception'); END;

执行、删除存储函数

-- 执行该函数
DECLARE
v_sum NUMBER;
v_count NUMBER;
BEGIN
v_sum := get_salary(80, v_count);
-- v_sum := get_salary(dep_id => 80, emp_count => v_count);
dbms_output.put_line('80号部门工资总数: ' || v_sum || ',人数:' || v_count);
END; -- 删除
DROP FUNCTION get_salary;
3、存储过程
eg、根据员号查询员工工资
CREATE OR REPLACE PROCEDURE query_emp_salary(
v_empid employees.employee_id%TYPE,
v_name OUT employees.last_name%TYPE,
v_sal OUT employees.salary%TYPE
)
AS BEGIN SELECT last_name, salary INTO v_name, v_sal
FROM employees
WHERE employee_id = v_empid;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('No data found');
WHEN OTHERS THEN
dbms_output.put_line('Other Exception'); END;
执行、删除存储过程
-- 执行该存储过程
DECLARE
v_1 employees.employee_id%TYPE;
v_2 employees.last_name%TYPE;
BEGIN
query_emp_salary(60, v_1, v_2);
dbms_output.put_line('name: : ' || v_1 || ',salary:' || v_2);
END; -- 删除
DROP PROCEDURE query_emp;
二、包的创建和应用
 
1、What's 包?
①、包是一组相关过程、函数、变量、常量和游标等 PL/SQL 程序设计元素的组合,是对这些 PL/SQL 程序设计元素的封装。(好像JAVA中的类,可以定义各种方法)
②、使用包不仅可以使程序设计模块化,还可以对外隐藏包内所使用的信息(通过使用私
用变量)
③、当程序首次调用包内函数或过程时, ORACLE 将整个包调入内存,当再次访问包内元素时, ORACLE 直接从内存中读取,而不需要进行磁盘 I/O 操作,从而使程序执行效率得到提高。
 
2、包的组成(包定义、包主体)
①、包定义(PACKAGE):声明包内数据类型、游标、函数、过程、异常,这些元素为包的公有元素。
②、包主体(PACKAGE BODY):包定义部分的具体实现,在包主体中可以定义包的私有元素
 
注意:包定义和包主体分开编译,并作为两部分分开的对象存放在数据库字典中,详见数据字典 user_source、all_source、 dba_source.
 
3、包的实现:
eg、创建的包为 demo_pack, 该包中包含一个记录变量 DeptRec、一个函数和一个过程。
包定义:
-- demo_pack 包定义:
CREATE OR REPLACE PACKAGE demo_pack
AS
deptRec departments%ROWTYPE; -- 声明游标
FUNCTION add_dept(dept_no NUMBER, dept_name VARCHAR2) -- 声明函数
RETURN NUMBER;
PROCEDURE query_dept(dept_no IN NUMBER); -- 声明存储过程
END demo_pack;
包主体:
-- demo_pack 包主体:
CREATE OR REPLACE PACKAGE BODY demo_pack
AS -- 创建 add_demp 函数
FUNCTION add_dept(dept_no NUMBER, dept_name VARCHAR2)
RETURN NUMBER
AS
empno_remaining EXCEPTION; -- 声明异常
PRAGMA exception_init(empno_remaining, -1); -- -1位违反唯一约束错误
BEGIN
INSERT INTO departments(department_id, department_name)
VALUES(dept_no, dept_name);
IF SQL%FOUND THEN
RETURN 1;
END IF;
EXCEPTION
WHEN empno_remaining THEN
RETURN 0;
WHEN OTHERS THEN
RETURN -1;
END add_dept; -- 创建 query_dept 存储过程
PROCEDURE query_dept(dept_no IN NUMBER)
AS
BEGIN
SELECT * INTO deptRec FROM departments WHERE department_id = dept_no;
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line('no_data_found exception');
WHEN OTHERS THEN
dbms_output.put_line('Other exception');
END query_dept; BEGIN
NULL;
END demo_pack;
demo_pack 包的调用:对包内共有元素的调用格式为:包名.元素名称
DECLARE
v1 NUMBER;
BEGIN v1 := demo_pack.add_dept(900, 'dept-A'); IF v1 = -1 THEN
dbms_output.put_line(SQLCODE || ': ' || SQLERRM);
ELSIF v1 = 0 THEN
dbms_output.put_line('部门存在啊');
ELSE
dbms_output.put_line('SUCCESS');
demo_pack.query_dept(900);
dbms_output.put_line('ID: ' || demo_pack.deptRec.department_id ||
', dept-name: ' || demo_pack.deptRec.department_name );
END IF;
END;
三、触发器
 
1、What's 触发器?
①、触发器是当某个事件发生时自动地触发另一个事件。所以运行触发器就叫触发或点火(^^)。
②、ORACLE 事件指的是对数据库的表进行的INSERT、 UPDATE 及 DELETE 操作或对视图进行类似的操作。 ORACLE 将触发器的功能扩展到了触发 ORACLE,如数据库的启动与关闭等。
 
2、触发器类型
  2.1 DML 触发器
    可以在 DML 操作前或操作后进行触发,并且可以对每个行或语句操作上进行触发。
  2.2 替代触发器
    由于在 ORACLE 里,不能直接对由两个以上的表建立的视图进行操作。所以给出了替代触发器。
  2.3 系统触发器
    它可以在 ORACLE 数据库系统的事件中进行触发,如 ORACLE 系统的启动与关闭等
 
3、触发器组成:
触发事件:INSERT, UPDATE, DELETE。
触发时间:触发事件发生之前( BEFORE)还是之后(AFTER)触发
触发器本身: TRIGGER 触发之后的目的和意图
触发频率:说明触发器内定义的动作被执行的次数。即语句级(STATEMENT)触发器和行级(ROW)触发器。
 
注意:
①、语句级(STATEMENT)触发器:是指当某触发事件发生时,该触发器只执行一次;
行级(ROW)触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次。
②、当省略 FOR EACH ROW 选项时, BEFORE 和 AFTER 触发器为语句触发器,而 INSTEAD OF 触发器则为行触发器。
 
4、创建触发器
4.1、DML 触发器
类型:
BEFORE INSERT
BEFORE INSERT FOR EACH ROW
AFTER INSERT
AFTER INSERT FOR EACH ROW BEFORE UPDATE
BEFORE UPDATE FOR EACH ROW
AFTER UPDATE
AFTER UPDATE FOR EACH ROW BEFORE DELETE
BEFORE DELETE FOR EACH ROW
AFTER DELETE
AFTER DELETE FOR EACH ROW
问题:当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、后列的值。
解决:   :new ------修饰符访问操作完成后列的值
      :old  ------修饰符访问操作完成前列的值
pl/sql 笔记之存储过程、函数、包、触发器(下)
eg、把职工表被删除记录写到职工表删除日志表中:
CREATE OR REPLACE TRIGGER del_emp_trigger
BEFORE DELETE ON employees FOR EACH ROW BEGIN INSERT INTO emp_temp(employee_id, first_name, last_name)
VALUES(:old.employee_id, :old.first_name, :OLD.last_name); END;
 
4.2、替代(INSTEAD OF)触发器
①、INSTEAD OF 触发器,只能对视图和对象视图建立 INSTEAD OF触发器,而不能对表、模式和数据库建立 INSTEAD OF 触发器
②、只能对视图和对象视图建立 INSTEAD OF触发器,而不能对表、模式和数据库建立 INSTEAD OF 触发器
 
eg、删除视图emp_view 中的数据
-- 删除视图数据非法
DELETE FROM emp_view WHERE employee_id = 100 -- 解决方法: INSTEAD OF 触发器 CREATE OR REPLACE TRIGGER emp_view_del
INSTEAD OF DELETE ON emp_view FOR EACH ROW
BEGIN
DELETE FROM employees WHERE employee_id = :old.employee_id;
END emp_view_del;
 
4.3、创建系统事件触发器
  系统事件触发器可以在 DDL 或数据库系统上被触发。
  ①、DDL 指的是数据定义语言,如CREATE 、 ALTER 及 DROP 等。
  ②、数据库系统事件包括数据库服务器的启动或关闭,用户的登录与退出、数据库服务错误等。
 
4.4、触发器状态
注意: 当删除表或视图时,建立在这些对象上的触发器也随之删除。
  有效状态(ENABLE):当触发事件发生时,处于有效状态的数据库触发器 TRIGGER 将被触发。
  无效状态(DISABLE):当触发事件发生时,处于无效状态的数据库触发器 TRIGGER 将不会被触发,就跟没有这个数据库触发器(TRIGGER) 一样
FOR EXAMPLE:
ALTER TRIGGER emp_view_delete DISABLE(ENABLE);

pl/sql 笔记之存储过程、函数、包、触发器(下)的更多相关文章

  1. 【Java EE 学习 29 上】【PL/SQL】【存储过程】【存储函数】【触发器】

    一.PL/SQL简介 1.概念:PL/SQL语言是Oracle数据库专用的一种高级程序设计语言,是对标准SQL语言进行了过程化扩展的语言. 2.功能:既能够实现对数据库的操作,也能够通过过程化语言中的 ...

  2. 查看SQL SERVER 加密存储过程,函数,触发器,视图

    原文:查看SQL SERVER 加密存储过程,函数,触发器,视图 create  PROCEDURE sp_decrypt(@objectname varchar(50))ASbeginset noc ...

  3. MySQL mysqldump 导入/导出 结构&数据&存储过程&函数&事件&触发器

    ———————————————-库操作———————————————-1.①导出一个库结构 mysqldump -d dbname -u root -p > xxx.sql ②导出多个库结构 m ...

  4. 在PL/SQL中调用存储过程--oracle

    在oracle10中写好了存储过程,代码如下: CREATE OR REPLACE Procedure Proc_Insert ( sName in varchar2, sAge in int, sE ...

  5. PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验

    PL/SQL Developer 在windows7 64位系统下连Oaracle11g64位系统的解决经验 一.问题现象及解决方法 现象: 1.PL/SQL 无法登录64位数据库 2.在PL/SQL ...

  6. Oracle PL/SQL异常、存储过程和触发器

    一.异常 1.处理异常 (1)除数不为0 declare b number; begin b:; exception when zero_divide then dbms_output.put_lin ...

  7. oracle-游标-存储过程-函数-包

    一.存储过程 不可以在insert,update,delete中直接使用,可以有return但代表的是退出过程 过程有三种类型:不返回值,可以返回多个值,参数有三种类型,分别如下: in:只输入,不返 ...

  8. pl/sql 笔记之基础(上)

    由于公司中使用 oracle,而本人对存储过程一直也懵懵懂懂,故一周时间学习了一遍 pl/sql,在此记下笔记!!! 一.前提,pl/sql 是啥? 1.PL/SQL是一种高级数据库程序设计语言,该语 ...

  9. PL SQL笔记(三)

    loop then .. exit; end if; end loop; select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') from dual; sel ...

随机推荐

  1. 基于SPSS的美国老年夏季运动会运动员数据分析

             本文是课程训练的报告,部分图片由于格式原因并没有贴出,有兴趣者阅读完整报告者输入以下链接 http://files.cnblogs.com/files/liugl7/基于SPSS的老 ...

  2. 远程连接MySql连不上1130

    mysql数据库user表中已存在主机=%的用户root,连接却提示1130. 用navicat开启user表>>>>在表里直接修改%账户root的密码(看到是未加密过的内容) ...

  3. jQuery中$.get、$.post、$.getJSON和$.ajax的用法

    以下是本人原创,如若转载和使用请注明转载地址.本博客信息切勿用于商业,可以个人使用,若喜欢我的博客,请关注我,谢谢!博客地址 一.jQuery中调用ajax的4种方法:$.get.$.post.$ge ...

  4. Spring Boot Document Part II(下)

    Part II. Getting started 11. 开发第一个Spirng Boot Application使用Spring Boot的关键特征开发一个基于JAVA Web的“Hello Wor ...

  5. 团队作业4——第一次项目冲刺(Alpha版本)2017.11.16

    第一次会议:2017-11-16 大家的任务完成的不错^_^,继续努力了. 上图: 忘记照了,额....... 会议主要内容: 1.登录功能的讨论 2. 代码统一 具体分工: 成员 计划任务 遇见难题 ...

  6. .net core页面使用layui的HtmlHelper扩展

    Vino.Core.Extensions.Layui 如果您的.net core 2.0项目使用layui来渲染表单,那么您可以尝试使用这个扩展库可以帮你减少代码和工作量. 项目地址:https:// ...

  7. 微服务领域是不是要变天了?Spring Cloud Alibaba正式入驻Spring Cloud官方孵化器!

    引言 微服务这个词的热度自它出现以后,就一直是高烧不退,而微服务之所以这么火,其实和近几年互联网的创业氛围是分不开的. 与传统行业不同,互联网企业有一个特点,那就是市场扩张速度非常之快,可能也就是几天 ...

  8. java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider

    今天部署完一个测试war包,打开页面的时候报错: HTTP Status 500 - Handler processing failed; nested exception is java.lang. ...

  9. C 中的typedef应用

    1. typedef  声明的新的类型名在变量名的位置出现. example: typedef unsigned int UINT 则 unsigned int a; 相当于 UINT A; 2. t ...

  10. SpringBoot入门学习记录(一)

    最近,SpringBoot.SpringCloud.Dubbo等框架非常流行,作为Coder里的一名小学生,借着改革开放的东风,自然也是需要学习学习的,于是将学习经历记录于此,以备日后查看. 官网:h ...