20.Oracle11g中的触发器

oracle11g中的触发器

  • 一、触发器的概述
    • 1、什么是触发器
    • 2、触发器的类型
    • 3、触发器的组成
    • 4、触发器的作用
  • 二、触发器的创建语法
    • 1、创建语法
    • 2、数据库启动触发器
    • 3、 用户登录触发器:
  • 三、对触发器的基本操作
  • 点击此处跳转下一节:21.Oracle的程序包(Package)

一、触发器的概述

1、什么是触发器

触发器是一种特殊的存储过程,它是一段PL/SQL代码,可以在特定的数据库操作(如INSERT、UPDATE、DELETE)发生时自动执行。触发器可以用来实现数据约束、数据审计、数据复制等功能。

  • 触发器是当特定事件出现时自动执行的存储过程
    • 提供审计和日志记录
    • 启用复杂的业务逻辑
  • 特定事件可以是执行更新的DML语句和DDL语句
    • 自动生成数据
    • 自定义复杂的安全权限
  • 触发器不能被显式调用

2、触发器的类型

在这里插入图片描述

Oracle11g中的DML触发器分为三种类型:

  • 行级触发器:对于每一行数据的操作都会触发该触发器。
  • 语句级触发器:对于每一条SQL语句的操作都会触发该触发器。
  • 复合触发器:既可以作为行级触发器,也可以作为语句级触发器。

3、触发器的组成

  1. 常见触发器由以下三部分组成

    • 触发器语句(事件)
      • 定义激活触发器的 DML 事件和 DDL 事件
    • 触发器限制
      • 执行触发器的条件,该条件必须为真才能激活触发器
    • 触发器操作(主体)
      • 包含一些 SQL 语句和代码,它们在发出了触发器语句且触发限制的值为真时运行
  2. 在Oracle 11g中,触发器由以下几个主要组成部分构成

    • 触发器名称(Trigger Name)
      • 触发器的名称是唯一的,用于标识触发器。在创建触发器时,需要为触发器指定一个名称,并且在数据库中触发器的名称是唯一的。
    • 触发时机(Triggering Event)
      • 触发器可以在不同的操作时机被触发,包括BEFOREAFTERINSTEAD OFBEFORE表示在操作执行之前触发,AFTER表示在操作执行之后触发,INSTEAD OF用于视图触发器。
    • 触发的操作类型(Triggering Action)
      • 触发器可以响应不同类型的数据库操作,包括INSERTUPDATEDELETE等。此外,还可以使用组合形式,比如INSERT OR UPDATEUPDATE OR DELETE等。
    • 触发的表(Triggering Table)
      • 触发器可以绑定到特定的数据库表上,当表上的操作符合触发条件时,触发器会被激活。
    • 触发器逻辑(Trigger Logic)
      • 触发器逻辑定义了触发器被激活时所执行的操作。这部分通常包含在BEGINEND之间,可以包括各种PL/SQL语句和逻辑。
    • 引用新旧值(Referencing New/Old Values)
      • 在行级触发器中,可以使用NEWOLD关键字来引用被操作的行的新旧值。这样可以在触发器逻辑中对新旧值进行比较和操作。
    • 触发条件(Trigger Condition)
      • 在行级触发器中,可以使用WHEN关键字来指定触发条件,只有当条件满足时触发器才会被激活。
    • 触发器类型(Trigger Type)
      • 触发器可以是行级触发器(FOR EACH ROW)或者语句级触发器(FOR EACH STATEMENT)。行级触发器会在每行被操作时触发,而语句级触发器会在每个SQL语句执行时触发。

    以上是Oracle 11g触发器的主要组成部分,了解这些组成部分可以帮助我们更好地理解和设计触发器,以满足特定的业务需求。

4、触发器的作用

  1. 实现数据约束:通过触发器可以对特定的数据库操作进行限制,从而保证数据的完整性和一致性。

    当使用触发器实现数据约束时,可以在触发器中编写逻辑来检查插入、更新或删除的数据是否符合特定的约束条件。以下是一个简单的示例,演示了如何使用触发器实现数据约束:

    假设我们有一个名为employee的表,包含以下字段:employee_id, employee_name, salary。我们希望在每次更新员工的薪水时,自动检查薪水是否在有效范围内(例如,不能低于最低工资,不能高于最高工资)。

    首先,我们创建一个触发器,当有员工的薪水被更新时,自动检查薪水是否在有效范围内。

    CREATE OR REPLACE TRIGGER check_salary_range_trigger
    BEFORE UPDATE OF salary ON employee
    FOR EACH ROW
    BEGINIF :NEW.salary < 1000 THENRAISE_APPLICATION_ERROR(-20001, 'Salary cannot be less than 1000');ELSIF :NEW.salary > 100000 THENRAISE_APPLICATION_ERROR(-20002, 'Salary cannot exceed 100000');END IF;
    END;
    /
    

    在上面的代码中,我们创建了一个名为check_salary_range_trigger的触发器。它是一个行级触发器(FOR EACH ROW),当员工的薪水被更新前(BEFORE UPDATE OF salary ON employee)触发器会检查薪水是否在有效范围内。如果薪水不在有效范围内,触发器会抛出一个自定义的应用程序错误,从而阻止薪水更新操作。

    现在,当我们尝试更新员工的薪水时,触发器会自动检查薪水是否在有效范围内,如果不符合约束条件,更新操作将被阻止并抛出相应的错误信息。

    这就是一个简单的触发器示例,说明了触发器在实现数据约束功能时的作用。其他的数据约束也可以通过类似的方式在触发器中实现。


  2. 实现数据审计:通过触发器可以记录特定的数据库操作,从而实现数据审计的功能。

    假设我们有一个名为employee的表,包含以下字段:employee_id, employee_name, salary。我们希望在每次有新员工加入时,自动记录员工加入的时间。

    首先,我们创建一个新的表employee_audit,用于记录员工加入的时间。表的结构如下:

    CREATE TABLE employee_audit (employee_id NUMBER,join_date DATE
    );
    

    接下来,我们创建一个触发器,当有新员工加入时,自动将员工的ID和加入时间插入到employee_audit表中。

    CREATE OR REPLACE TRIGGER employee_join_trigger
    AFTER INSERT ON employee
    FOR EACH ROW
    BEGININSERT INTO employee_audit (employee_id, join_date)VALUES (:NEW.employee_id, SYSDATE);
    END;
    /
    

    在上面的代码中,我们创建了一个名为employee_join_trigger的触发器。它是一个行级触发器(FOR EACH ROW),当有新的员工被插入(AFTER INSERT ON employee)时,触发器会将员工的ID和加入时间插入到employee_audit表中。

    现在,当我们向employee表中插入新的员工记录时,触发器会自动将员工的ID和加入时间记录到employee_audit表中,从而实现了数据审计的功能。

    这就是一个简单的触发器示例,说明了触发器在实现数据审计功能时的作用。其他的触发器功能也可以通过类似的方式实现。


  3. 实现数据复制:通过触发器可以在不同的数据库之间实现数据的复制。

    当使用触发器实现数据复制时,可以在触发器中编写逻辑来将插入、更新或删除的数据复制到另一个表中。以下是一个简单的示例,演示了如何使用触发器实现数据复制:

    假设我们有一个名为employee的表,包含以下字段:employee_id, employee_name, salary。我们希望在每次有新员工加入时,自动将员工的信息复制到另一个表employee_copy中。

    首先,我们创建一个新的表employee_copy,用于存储复制的员工信息。表的结构与employee表相同。

    CREATE TABLE employee_copy (employee_id NUMBER,employee_name VARCHAR2(100),salary NUMBER
    );
    

    接下来,我们创建一个触发器,当有新员工加入时,自动将员工的信息复制到employee_copy表中。

    CREATE OR REPLACE TRIGGER employee_copy_trigger
    AFTER INSERT ON employee
    FOR EACH ROW
    BEGININSERT INTO employee_copy (employee_id, employee_name, salary)VALUES (:NEW.employee_id, :NEW.employee_name, :NEW.salary);
    END;
    /
    

    在上面的代码中,我们创建了一个名为employee_copy_trigger的触发器。它是一个行级触发器(FOR EACH ROW),当有新的员工被插入(AFTER INSERT ON employee)时,触发器会将员工的ID、姓名和薪水插入到employee_copy表中。

    现在,当我们向employee表中插入新的员工记录时,触发器会自动将员工的信息复制到employee_copy表中,从而实现了数据复制的功能。

    这就是一个简单的触发器示例,说明了触发器在实现数据复制功能时的作用。其他的数据复制也可以通过类似的方式在触发器中实现。


  4. 实现业务逻辑:通过触发器可以实现特定的业务逻辑,从而简化应用程序的开发和维护。

    假设我们有一个名为orders的表,包含以下字段:order_id, order_date, total_amount。我们希望在每次有新订单插入时,自动更新客户的最近订单日期。

    以下是一个示例代码,演示了如何使用触发器实现这个业务逻辑:

    首先,我们创建一个名为customer的表,包含以下字段:customer_id, customer_name, last_order_datelast_order_date字段用于存储客户的最近订单日期。

    CREATE TABLE customer (customer_id NUMBER,customer_name VARCHAR2(100),last_order_date DATE
    );
    

    接下来,我们创建一个触发器,当有新订单插入时,自动更新客户的最近订单日期。

    CREATE OR REPLACE TRIGGER update_last_order_date_trigger
    AFTER INSERT ON orders
    FOR EACH ROW
    BEGINUPDATE customerSET last_order_date = :NEW.order_dateWHERE customer_id = :NEW.customer_id;
    END;
    /
    

    在上面的代码中,我们创建了一个名为update_last_order_date_trigger的触发器。它是一个行级触发器(FOR EACH ROW),当有新的订单被插入(AFTER INSERT ON orders)时,触发器会自动更新对应客户的最近订单日期。

    现在,当我们向orders表中插入新的订单记录时,触发器会自动更新对应客户的最近订单日期,从而实现了业务逻辑的功能。

    这就是一个简单的触发器示例,说明了触发器在实现业务逻辑时的作用。其他的业务逻辑也可以通过类似的方式在触发器中实现。


  5. 实现性能优化:通过触发器可以对特定的数据库操作进行优化,从而提高系统的性能。

    触发器可以用于实现性能优化,例如在数据更新时进行一些计算或者更新其他相关的数据。以下是一个示例代码,演示了如何使用触发器实现性能优化:

    假设我们有一个名为order_items的表,包含以下字段:order_id, item_id, quantity, unit_price。我们希望在每次插入或更新订单项时,自动更新订单的总金额。

    首先,我们创建一个名为orders的表,包含以下字段:order_id, order_date, total_amounttotal_amount字段用于存储订单的总金额。

    CREATE TABLE orders (order_id NUMBER,order_date DATE,total_amount NUMBER
    );
    

    接下来,我们创建一个触发器,当有新的订单项插入或更新时,自动更新订单的总金额。

    CREATE OR REPLACE TRIGGER update_order_total_amount_trigger
    AFTER INSERT OR UPDATE ON order_items
    FOR EACH ROW
    BEGINIF INSERTING THENUPDATE ordersSET total_amount = total_amount + (:NEW.quantity * :NEW.unit_price)WHERE order_id = :NEW.order_id;ELSIF UPDATING THENUPDATE ordersSET total_amount = total_amount - (:OLD.quantity * :OLD.unit_price) + (:NEW.quantity * :NEW.unit_price)WHERE order_id = :NEW.order_id;END IF;
    END;
    /
    

    在上面的代码中,我们创建了一个名为update_order_total_amount_trigger的触发器。它是一个行级触发器(FOR EACH ROW),当有新的订单项被插入或更新(AFTER INSERT OR UPDATE ON order_items)时,触发器会自动更新对应订单的总金额。

    在触发器中,我们使用了条件语句来区分插入和更新操作,以便在每种情况下都能正确更新订单的总金额。

    现在,当我们向order_items表中插入或更新订单项时,触发器会自动更新对应订单的总金额,从而实现了性能优化的功能。

    这就是一个简单的触发器示例,说明了触发器在实现性能优化时的作用。其他的性能优化也可以通过类似的方式在触发器中实现。


总之,触发器是Oracle数据库中非常重要的一个功能,它可以帮助我们实现很多有用的功能,并且可以提高系统的性能和可维护性。在使用触发器时,需要注意避免过度使用,以免对系统性能产生负面影响。


二、触发器的创建语法

1、创建语法

在Oracle 11g中,可以使用以下语法来创建触发器:

CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF} {INSERT | UPDATE | DELETE | {INSERT OR UPDATE} | {UPDATE OR DELETE} | {INSERT OR DELETE} | {INSERT OR UPDATE OR DELETE}}
ON table_name
[REFERENCING {NEW AS new | OLD AS old | NEW AS new OLD AS old}]
[FOR EACH ROW | FOR EACH STATEMENT]
[WHEN (condition)]
BEGIN-- 触发器逻辑
END;
/

下面是对上述语法中各个部分的详细介绍:

  1. CREATE [OR REPLACE] TRIGGER trigger_name:用于创建一个新的触发器。OR REPLACE关键字表示如果同名的触发器已经存在,则替换掉原有的触发器。

  2. {BEFORE | AFTER | INSTEAD OF}:指定触发器的触发时机,BEFORE表示在操作执行前触发,AFTER表示在操作执行后触发,INSTEAD OF用于视图触发器。

  3. {INSERT | UPDATE | DELETE | {INSERT OR UPDATE} | {UPDATE OR DELETE} | {INSERT OR DELETE} | {INSERT OR UPDATE OR DELETE}}:指定触发器要响应的操作类型。可以是单个操作类型,也可以是多个操作类型的组合。

  4. ON table_name:指定触发器要绑定的表名。

  5. [REFERENCING {NEW AS new | OLD AS old | NEW AS new OLD AS old}]:用于在触发器逻辑中引用新旧值。NEW表示新值,OLD表示旧值。

  6. [FOR EACH ROW | FOR EACH STATEMENT]:指定触发器是行级触发器还是语句级触发器。FOR EACH ROW表示行级触发器,FOR EACH STATEMENT表示语句级触发器。

  7. [WHEN (condition)]:可选项,用于在行级触发器中指定触发条件。

  8. BEGIN ... END;:在BEGINEND之间包含了触发器的逻辑代码。

  9. 触发器逻辑:在BEGINEND之间的部分是触发器的逻辑代码,用于定义触发器要执行的操作。

  10. /:表示SQL语句的结束。

通过以上语法,可以在Oracle 11g中创建各种类型的触发器,用于实现特定的业务逻辑或性能优化。

2、数据库启动触发器

数据库启动触发器是在数据库启动时自动执行的触发器,它可以用于执行一些初始化操作。在Oracle数据库中,可以使用AFTER STARTUP触发器来实现数据库启动触发器。以下是一个简单的示例:

CREATE OR REPLACE TRIGGER startup_trigger
AFTER STARTUP
ON DATABASE
BEGIN-- 在数据库启动时执行的操作DBMS_OUTPUT.PUT_LINE('Database has been started');-- 可以在这里添加其他需要执行的初始化操作
END;
/

在上面的示例中,我们创建了一个名为startup_trigger的触发器,它在数据库启动后执行。在触发器的BEGINEND之间可以编写需要在数据库启动时执行的操作。

示例如下:
这段SQL包含了两部分操作:

CREATE TABLE event_table (event varchar2(30), time  date);

这部分SQL用来创建一个名为event_table的表,表中包含了事件(event)和时间(time)两个字段。这个表似乎是用来记录不同事件和它们发生的时间。

CREATE OR REPLACE TRIGGER tr_startupAFTER startup ON DATABASE
BEGININSERT INTO event_table VALUES (ora_sysevent, SYSDATE);
END;

这部分SQL用来创建一个名为tr_startup的触发器,它是一个“after startup”类型的触发器,意味着它会在数据库启动后触发。当数据库启动时,触发器会将当前系统事件(ora_sysevent)和当前时间(sysdate)插入到event_table表中。

这样,当数据库启动时,触发器会自动将相关信息记录到event_table表中,从而实现了记录数据库启动事件的功能。

3、 用户登录触发器:

用户登录触发器是在用户登录到数据库时自动执行的触发器,它可以用于记录用户登录信息、执行安全检查等操作。在Oracle数据库中,可以使用AFTER LOGON触发器来实现用户登录触发器。以下是一个简单的示例:

CREATE OR REPLACE TRIGGER login_trigger
AFTER LOGON
ON DATABASE
BEGIN-- 在用户登录时执行的操作DBMS_OUTPUT.PUT_LINE('User ' || USER || ' has logged in');-- 可以在这里添加其他与用户登录相关的操作
END;
/

在上面的示例中,我们创建了一个名为login_trigger的触发器,它在用户登录后执行。在触发器的BEGINEND之间可以编写需要在用户登录时执行的操作,例如记录用户登录信息、执行权限检查等。
示例如下:

CREATE TABLE log_table(username  varchar2(20), logon_time  date, logoff_time  date, address varchar2(20));

这部分SQL用来创建一个名为log_table的表,表中包含了用户名(username)、登录时间(logon_time)、登出时间(logoff_time)和地址(address)等字段。

CREATE OR REPLACE TRIGGER tr_logonAFTER logon ON DATABASE
BEGININSERT INTO log_table(username, logon_time, address)VALUES(ora_login_user, SYSDATE, ora_client_ip_address);
END;

这部分SQL用来创建一个名为tr_logon的触发器,它是一个“after logon”类型的触发器,意味着它会在用户登录后触发。当用户登录时,触发器会将当前登录用户(ora_login_user)、登录时间(sysdate)和客户端IP地址(ora_client_ip_address)插入到log_table表中。

oracle常用系统变量- Ora_client_ip_address 返回客户端的ip地址- Ora_database_name 返回当前数据库名- Ora_login_user 返回登录用户名- Ora_dict_obj_name 返回ddl操作所对应的数据库对象名 - Ora_dict_obj_type 返回ddl操作所对应的数据库对象的类型  

oracle常用系统变量

这样,当用户登录数据库时,触发器会自动将相关信息记录到log_table表中,从而实现了用户登录日志的记录功能。


通过使用数据库启动触发器和用户登录触发器,可以在数据库启动和用户登录时执行一些必要的操作,从而提高数据库的安全性和可靠性。

三、对触发器的基本操作

在Oracle 11g中,可以通过以下方式对触发器进行基本操作:启用、禁用、删除、查看触发器的基本信息。

  1. 启用触发器:

    ALTER TRIGGER trigger_name ENABLE;
    
  2. 禁用触发器:

    ALTER TRIGGER trigger_name DISABLE;
    
  3. 删除触发器:

    DROP TRIGGER trigger_name;
    
  4. 查看触发器的基本信息:

    SELECT trigger_name, table_name, triggering_event
    FROM user_triggers;
    

    这条查询语句将返回当前用户拥有的所有触发器的名称(trigger_name)、所属表名(table_name)和触发事件(triggering_event)的信息。

通过以上操作,可以对Oracle 11g中的触发器进行启用、禁用、删除以及查看基本信息的操作。

点击此处跳转下一节:21.Oracle的程序包(Package)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/231286.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis的过期策略以及定时器的实现

Redis是客户端服务器结构的程序&#xff0c;客户端与服务器通过网络通信&#xff0c;所以对于keys *这种的操作在大型企业中不太建议&#xff0c;生产环境下的key会非常多&#xff0c;Redis是但现成的服务器&#xff0c;执行keys*的时间非常长&#xff0c;就会导致redis服务器阻…

【LeetCode】101. 对称二叉树

101. 对称二叉树 难度&#xff1a;简单 题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#…

token认证机制,基于JWT的Token认证机制实现,安全性的问题

文章目录 token认证机制几种常用的认证机制HTTP Basic AuthOAuthCookie AuthToken AuthToken Auth的优点 基于JWT的Token认证机制实现JWT的组成认证过程登录请求认证 对Token认证的五点认识JWT的JAVA实现 基于JWT的Token认证的安全问题确保验证过程的安全性如何防范XSS Attacks…

Redis 基础、字符串、哈希、有序集合、集合、列表以及与 Jedis 操作 Redis 和与 Spring 集成。

目录 1. 数据类型 1.1 字符串 1.2 hash 1.3 List 1.4 Set 1.5 sorted set 2. jedis操作redis 3. 与spring集成 1. 数据类型 1.1 字符串 String是最常用的数据格式&#xff0c;普通的kay-value都归结为此类&#xff0c; value值不仅可以是string&#xff0c;可以是数字…

interface previously declared 的bug问题

其实就是重复定义了&#xff0c;只需要加如下的代码即可&#xff1a; 其中把APB的部分改成自己的接口名字就好了。

JS 绘制半径不一致的环形图进度条

HTML部分: <canvas id"mycanvas" width"100" height"100"></canvas>JS部分&#xff1a; const option {element: "mycanvas", // 元素count: 26, // 高亮数据totalCount: 129, // 总数据progressColor: #3266FB, // 进…

工会排队奖励模式:创新营销策略,实现共赢局面

在当今的商业环境中&#xff0c;创新营销策略的重要性日益凸显。工会排队奖励模式作为一种新型的营销策略&#xff0c;旨在通过结合线上和线下消费&#xff0c;激励消费者购买产品或服务&#xff0c;并获得返现奖励。这种模式通过将消费者的支出和商家的抽成资金纳入奖金池&…

goweb入门教程

本文是作者自己学习goweb时写的笔记&#xff0c;分享给大家&#xff0c;希望能有些帮助 前言&#xff1a; 关于web&#xff1a;本质 ​ ​ web中最重要的就是浏览器和服务器的request(请求)和response(响应)&#xff1b; ​ 一个请求对应一个响应。 一个请求对应一个响应&…

微信群发消息怎么发?如何突破200人限制?(最全攻略)

每到节假日或者各种大促节日&#xff0c;很多人都会发布或收到微信好友的节日祝福或活动通知。群发已经是很普遍的一件事了。 说到微信群发&#xff0c;大家是不是还在用微信自带的群发功能&#xff0c;或者说还在手动进行群发操作“复制粘贴”的形式进行&#xff1f; 如果好友…

传感器:探索Android中的传感器功能与使用

传感器&#xff1a;探索Android中的传感器功能与使用 一、传感器介绍1.1 Android 平台三大类传感器1.2 Android 平台支持的传感器1.3 传感器框架 二、传感器的使用2.1 识别传感器和传感器特性2.2 针对不同制造商的传感器或传感器的不同版本优化2.3 监控传感器事件2.4 处理不同的…

明确涉密测绘成果使用审批流程和责任人,未经批准,涉密测绘成果不得带离保密要害部门部位

1.单位内部涉密测绘成果使用流程规章制度&#xff1b; 2.明确责任人及岗位等文件材料&#xff1b; 3.涉密测绘成果提供使用台账。

【开发实践】使用jstree实现文件结构目录树

一、需求分析 因开发系统的需要&#xff0c;维护服务端导出文件的目录结构。因此&#xff0c;需要利用jstree&#xff0c;实现前端对文件结构目录的展示。 【预期效果】&#xff1a; 二、需求实现 【项目准备】&#xff1a; jstree在线文档&#xff1a;jstree在线文档地址 …