关于触发器一些小结

我们为什么用触发器呢?

下面摘自部分官方文档:Automatically generate virtual column values(自动生成虚拟列值)

Log events(日志事件)Gather
statistics on table access(收集统计数据表的访问)

Modify table data when DML statements are issued against views(修改表数据的时候DML语句发表反对的意见)

Enforce referential integrity when child and parent tables are on different nodes of (强制引用完整性时,孩子和家长的表在不同的节点)

a distributed database一个分布式数据库Publish
information about database events, user events, and SQL statements to (发布信息数据库事件,用户事件,和SQL语句)

subscribing applications(订阅应用程序)

Prevent DML operations on a table after regular business hours(防止DML操作一个正在正常生产环境时间段的表)

Prevent invalid transactions(防止非法的事务)

Enforce complex business or referential integrity rules that you cannot define with constraints (执行复杂的业务或引用完整性规则,你不能定义约束)

下面简介介绍几种触发器(trigger涉及的内容较多,了解更多详细参考官方文档):

DML触发器:当发出UPDATE、INSERT、DELETE命令就可以触发已定义好的DML触发器(不能对sys用户创建的表建触发器)

语法:

create or replace trigger trigger_name

after|before insert|update|delete

on table_name

for each row

System触发器(database,ddl):(文档上概括为system触发器)

当发出CREATE、ALTER、DROP、TRUNCATE命令时会触发已定义好的DDL触发器,这种触发器可以用来监控某个用户或整个数据库的所有对象的结构变化

语法:

create or replace trigger trigger_name

before|after startup|shutdown|logon|logoff

on database

database事件触发器:当STARTUP、SHUTDOWN、LOGON、LOGOFF数据库时就会触发DB事件触发器,这种触发器可以用来监控数据库什么时候关闭/打,或者用户的LOGON/LOGOFF数据库情况

语法:

create or replace trigger trigger_name

before|after startup|shutdown|logon|logoff

on database

instead-of触发器(视图):当向一个由多个表联接成的视图作DML操作时,一般情况下是不允许的,这时候就可以用Instead-of触发器来解决这种问题(在触发器写代码分别对各表作相应DML操作),语法是这样的:
create or replace trigger trigger_name
instead of insert|update|delete
on view_name
for each row
下面以试验说明每一种触发器:
SQL> select * from v$version where rownum=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

SQL> show user;
USER 为 "HR"

DML触发器:禁止用CREATE、ALTER、DROP、TRUNCATE命令操作HR用户的对象
SQL> create table t_trigger(username varchar2(10),ip varchar2(10),time date,term
inal varchar2(10),event varchar2(10),id number(10),name varchar2(10));
表已创建。
 create or replace trigger tirgger_t
  after insert  on  t  
  for each row
declare
  -- local variables here
begin
  insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),‘insert‘,
  :new.id,:new.name);(这里记录的是插入后的值,如果换成:old.id,则此列值为空
end tirgger_t;
此时我们插入数据验证:
SQL> insert into t values(0,‘os‘);

已创建 1 行。
SQL> set linesize 1000;
SQL> set pagesize 1000;
SQL> select * from t_trigger;
USERNAME             IP                                       TIME           TER
MINAL                                 EVENT                        ID NAME
-------------------- ---------------------------------------- -------------- ---
------------------------------------- -------------------- ---------- ----------
----------
HR                   170.12.15.20                            19-4月 -15     PC2
01409141201                           insert                        0 os
注意::new,:old不能用在表级触发器中
在pl/sql中,提供了inseting,updating,deleting谓词用作流程语句中。
上述触发器如果写成一下形式:
create or replace trigger tirgger_t   after insert on t   -- for each row    注释此行 declare   -- local variables here begin   insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),‘insert‘,    null,null); end tirgger_t; 则只记录插入的第一行,for  ecah  row 失效。 System触发器:(不能基于表或视图) 
ddl触发器:
create or replace trigger t_tirgger_ddl
  after ddl on hr.schema      =>对于ddl触发器,可以直接写ddl,系统会识别何操作
declare
  -- local variables here
begin
  insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent,
 
 null,null);
end t_tirgger_ddl;
for  each row 不能用于对象触发器
对于schema,很多初学者很困惑,不知道这个是什么概念,这个逻辑概念很重要,指用户具有所有对象的集合。
SQL> alter table t add address varchar2(20);

表已更改。

SQL> select * from t_trigger;

USERNAME             IP                   TIME                 TERMINAL
    EVENT                        ID NAME
-------------------- -------------------- -------------------- -----------------
--- -------------------- ---------- --------------------

HR                  
170.12.15.20        19-4月 -15           PC201409141201

ALTER

db触发器:当STARTUP、SHUTDOWN、LOGON、LOGOFF数据库时就会触发DB事件触发器,这种触发器可以用来监控数据库什么时候关闭或打开,或者用户的LOGON/LOGOFF数据库情况(shutdown类型要用关键字before,startup用after)

create or replace trigger t_tirgger_db
  after logon on hr.schema
declare
  -- local variables here
begin
  insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent,
 
 null,null);
end t_tirgger_db;
重新连接:
SQL> select * from t_trigger;

USERNAME             IP                                       TIME
-------------------- ---------------------------------------- --------------
TERMINAL                                 EVENT                        ID
---------------------------------------- -------------------- ----------
NAME
--------------------
HR                  
170.12.15.20          
  LOGON     19-4月 -15  PC201409141201                         

同理也可以创建:

create or replace trigger t_tirgger_db
  after logoff  on hr.schema
declare
  -- local variables here
begin
  insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent,
 
 null,null);
end t_tirgger_db;
instead-of触发器:
SQL> create view t_view as select name,id from t;

视图已创建。

create or replace trigger t_tirgger_view
instead of insert on t_view
  for each row
declare
  -- local variables here
begin
  insert into t_trigger values(sys.login_user,sys_context(‘userenv‘,‘ip_address‘),sysdate,sys_context(‘userenv‘,‘terminal‘),sys.sysevent,
 
 :new.id,:new.name);
end t_tirgger_view;
SQL> insert into t_view values(‘0‘,0);
已创建 1 行。
SQL> select * from t_trigger;

USERNAME             IP                                       TIME
-------------------- ---------------------------------------- --------------
TERMINAL                                 EVENT                        ID
---------------------------------------- -------------------- ----------
NAME
--------------------
HR                  
170.12.15.20  
0        0
        19-4月 -15  PC201409141201        

删除触发器比较简单:

DROP TRIGGER trigger_name;当然你要有相关权限,在第三方工具中操作更加方便,如(pl/sql developer)


时间: 2024-10-13 08:08:56

关于触发器一些小结的相关文章

sql编程小结之触发器

对照mysql5.1手册,对这几天学的sql编程进行小结,主要涉及触发器.存储过程.权限管理.主从分离等,权当抛砖引玉,高手请略过. 一.触发器 通俗的说就是在指定的数据表增删改的前或后触发执行特定的sql语句,数据表为引用永久性表.不能将触发程序与TEMPORARY表或视图关联起来.可以从四个方面理解触发器: ---监视地点 table ---监视事件 insert/update/delete ---触发时间 after/before ---触发事件 insert/update/delete

由查找session IP 展开---函数、触发器、包

由查找session IP 展开---函数.触发器.包 一.userenv函数.sys_context函数 --查看当前客户端会话的session IP信息 SQL>select sys_context('userenv','ip_address') from dual; SYS_CONTEXT('USERENV','IP_ADDRESS') -----------------------------------------------------------------------------

T-SQL开发 - 10.IDENTITY属性使用小结

从SQL Server 2012开始有了Sequence,简单用列如下: CREATE SEQUENCE TestSeq START WITH 1 INCREMENT BY 1; SELECT NEXT VALUE FOR TestSeq AS NextValue; 在这之前,表中生成序列号大多都是借助IDENTITY列属性,当然也有一些时候,是在自定义表中,自己维护序列号. 一. 创建IDENTITY列 if OBJECT_ID('test','U') is not null     drop

机房收费系统学生下机结账小结

这几天一直在考虑机房收费系统学生下机操作.学生下机,一则须要加入学生下机记录信息:还须要计算学生在整 个上机过程中所花费的金额,而且更新学生剩余金额.那么如何做在性能上或者扩展上更好一些呢? 操作 1.加入学生下机信息 2.计算学生上机时间 3.依据上机时间来计算学生所花费的金额 4.更新学生的剩余金额 设计模式 在通过学生上机时间来计算学生所花费的金额这步操作上,须要进行一些条件分支语句的推断.由于上机时间被分为 了三部分:准备时间.至少上机时间.上机时间.所以在步骤3中有大量的条件分支语句,

10. IDENTITY属性使用小结

从SQL Server 2012开始有了Sequence,简单用列如下: CREATE SEQUENCE TestSeq START WITH 1 INCREMENT BY 1 ; SELECT NEXT VALUE FOR TestSeq AS NextValue; 在这之前,表中生成序列号大多都是借助IDENTITY列属性,当然也有一些时候,是在自定义表中,自己维护序列号. 一. 创建IDENTITY列 if OBJECT_ID('test','U') is not null drop ta

CI加载流程小结

无聊,决定水一把. CI(CodeIgniter)是我最早接触的一个框架,到现在也只是用了其中一点零碎的方法.一直想对其流程做个小结,却总是因各种各样的“理由”挨着.看见别人图表齐上阵,没那耐心,就从代码说起吧,权当做个笔记,纪念一下. 看在线的用户手册,也知道,将CI下载下来(最新版本2.2.1),解压到机子上,比如www目录,可改个根目录名(原名CodeIgniter-2.2-stable太长),初步目录文件如下,当然这在是windows下面.    访问下,如localhost/ci/in

数据库设计(7/9):触发器

对于设计和创建数据库完全是个新手?没关系,Joe Celko, 世界上读者数量最多的SQL作者之一,会告诉你这些基础.和往常一样,即使是最专业的数据库老手,也会给他们带来惊喜.Joe是DMBS杂志是多年来最受 读者喜爱的作者.他在美国.英国,北欧,南美及非洲传授SQL知识.他在ANSI / ISO SQL标准委员会工作了10年,为SQL-89和SQL-92标准做出了杰出贡献. 在第1篇到第4篇,我们创建了表,架构的基础和可视化.第5篇和第6篇讲了存储过程.这篇文章会讲述在触发器上,你需要尽量避免

MySQL 视图知识点小结

视图本身是一个虚拟表,不存放任何数据.在使用SQL语句访问视图的时候,它返回的数据是MySQL从其他表中生成的.视图和表在同一个命名空间, MySQL在很多地方对于视图和表是同样对待的.不过视图和表也有不同.例如,不能在视图上创建触发器,也不能用DROP TABLE命令删除视图. 视图的实现算法: 合并算法:merge 临时表算法:tmptable 可更新视图(updatable view):可以通过更新视图来更新视图涉及的相关表. 如果视图定义中包含了group by .union.聚合函数.

机房收费系统验收小结(二)

接着前面的,之前是一个小组系统进行的验收接下来的是另一组同学机房系统验收结: 充值 报表  1.整个机房系统最重要最重要的就是结账 输出,这系统最重要的功能 周结账,时间段,要有汇总 时间算账:最好以24小时进看起来方便 2.验收验收前:把之前的数据清空(数据库内的)  3.快捷键的注意:比如确定:回车键, 注册框:存盘应该在最左上方 提示图标,有不统一 4.写文档就按培养计划标准来: (1)开始标题 (2)誊写人,修改时间 (3)目录这些单独占一页 (4)甘特图少 "测试"时间段 (