Oracle数据库之触发器(二)
DML触发器
是指在进行insert、update或delete操作时触发的程序体。如果你想在用户对数据进行操作时,记录或限制其操作,就可以用DML触发器。
举例来说,我想统计我的网站用户的注册、注销或者更新个人信息等情况,我们就可以写如下一个触发器,每当有用户进行上述操作时,触发器会自动执行,并在log日志表中存储这些信息。
代码:
create or replace trigger user_log
before delete or insert or update
on users
for each row
declare
id number;
begin
select count(*)+1 into id from ts_log_users t;
if inserting then insert into ts_log_users t values (id,sysdate,(select count(*)+1 from ts_log_users t where t.class='create'),'create',:new.username);
elsif deleting then insert into ts_log_users t values (id,sysdate,(select count(*)-1 from ts_log_users where class='create'),'delete',:new.username);
else insert into ts_log_users t values (id,sysdate,(select t.count from ts_log_users t where create_date=(select max(t.create_date) from ts_log_users t)),'update',:new.username);
end if;
end;
第一行定义触发器名字为user_log,create or replace意思是建立或如果存在一样名字的触发器则覆盖。
第二行关键字可以选择before和after,即操作前和操作后。
比如我想查看用户登录的ip情况,这时我们需要在用户成功登录后触发触发器,所以需写after。
而这里要对用户的增删改敏感,所以选择before。后面是操作定义,即什么样的操作会触发触发器。
第三行on后面接表名,即当用户对这个表进行操作时,触发触发器。
另外,操作为update时,可写成before update of 列名 on 表名,来使限制更加具体化。
第四行将触发器定义为行级触发器,即每当一行数据发生变化时,就触发一次触发器。
比如我一下更新了三个用户的信息,那么log日志表中就会生成三条数据。
如果不写这句话,则触发器只会在上述操作时,触发一次,形成一条数据。
第五行声明变量,用于存储和操作一些可用数据。
从begin到end为程序主体,读起来也很容易理解,主要有两个操作,
一是将log日志的数据量+1作为数据id赋值给之前定义的id变量。赋值用into完成。
第二个操作是一个if操作,分别完成了对增删改不同情况的处理。
处理主要为想log日志表插入数据,
如果是新建用户的话,则向log日志表插入数据id(上面得到的)、系统时间、
目前用户数量(即count下log日志中是create操作的数据)、
操作类别(此处为create)以及操作的用户名(:new.的意思就是新修改的数据,对比:old.使用,这两个字段在更新操作时会经常用到。
例如将更新前的数据插入到另一表中,则用:old.表示,新插入的数据则用:new.操作)。后两个是对delete和update的操作,类似上面不在赘述。
替代触发器
这类触发器仅仅应用在视图上。我举个例子就明白这个触发器的用处了。比如说,我提供给初级管理员老张一个视图,只显示用户的基本注册信息,如用户名、性别、民族等,而隐藏了用户密码、身高、体重这些私密信息(这些信息存在表中,老张看不到,因为我没给他看表的权限)。但有一天有个走后门的找老张想把自己的信息加到我数据库中,于是老张就对视图进行插入操作。可是问题来了,当插入一条关系户数据到表中时,我们需要其用户密码、身高体重等(设置了不为空),而老张看不到因此插不进去,因此报错无法操作。所以这时我们就可以写一个替代触发器,即如果老张对视图操作时,后面的表会自动插入一些随机密码等,以完成老张的视图操作。触发器定义格式类似于上面,这里不再赘述(因为我没用视图,所以没写)。
系统触发器
是在进行系统操作如startup、drop、alter、logon等时才会触发的。
下面我写一个,因为我的数据库给了好多人使用,老张、老王等,而他们经常在别的时间和地点登录数据库,我想看看这些登录情况,因此我写一个登录的触发器:
代码:create or replace trigger oracle_user_log
after logon
on database
declare
id number;
begin
select count(*)+1 into id from ts_o_log_users t;
insert into ts_o_log_users values (id,sys.login_user,sysdate,ora_client_ip_address);
end;
另附一些参考代码:
create or replace trigger testtrigger
after insert on test1trige
for each row
declare v_flag number:=0;
begin
select count(0) into v_flag from test2trige where xh_id = :new.xh;
if v_flag = 0 then
insert into test2trige(xh_id,xsxm) values(:new.xh,:new.xm);
end if;
end;
create or replace trigger trig_jzg_RYLX after insert or update
on GXJG_JZGRYLXGX for each row
declare
v_sqlerrm varchar(4000);
v_count_n number:=0;
begin
select COUNT(0) into V_COUNT_n from bmryxxb@dblink_zfoa where yhm=:new.yhm and xydm in ('20140503','20140504','20140505','20140506');
if V_COUNT_n >0 and :new.yhlx not in('009','001') then
update bmryxxb@dblink_zfoa set xydm=decode(:new.yhlx,'2','20140503','006','20140504','008','20140505','004','20140506')--,'009','20140503')
where yhm=:old.yhm and xydm=decode(:old.yhlx,'2','20140503','006','20140504','008','20140505','004','20140506');
update bmryxxb@dblink_zfoa set xydm=decode(:new.yhlx,'2','20140503','006','20140504','008','20140505','004','20140506')--,'009','20140503')
where yhm=:new.yhm and xydm=(select xydm from bmryxxb@dblink_zfoa where yhm=:new.yhm and xydm in ('20140503','20140504','20140505','20140506'));
--else
-- insert into bmryxxb@dblink_zfoa
-- -- (xydm, jsdm, yhm, sjlsh)
-- values
-- (decode(:new.yhlx,'2','20140503','006','20140504','008','20140505','004','20140506'), '7', :new.yhm, '1');
end if;
select COUNT(0) into V_COUNT_n from bmryxxb@dblink_zfoa where yhm=:new.yhm and xydm in ('20140503','20140504','20140505','20140506');
if V_COUNT_n =0 then
insert into bmryxxb@dblink_zfoa
(xydm, jsdm, yhm, sjlsh)
values
(decode(:new.yhlx,'2','20140503','006','20140504','008','20140505','004','20140506'), '7', :new.yhm, '1');
end if;
select COUNT(0) into V_COUNT_n from yhb@dblink_zfoa where yhm=:new.yhm;
if V_COUNT_n >0 then
update yhb@dblink_zfoa set zdm=decode(:new.yhlx,'2','02','004','05','006','03','008','04','009','01','001','01') where yhm=:old.yhm;
end if;
--异常处理
Exception
WHEN OTHERS Then
v_sqlerrm := (Sqlerrm || chr(10) || dbms_utility.format_error_backtrace);
Insert Into XT_ERRLOG
Values
('办公系统',
'bmryxxbrylx',
'yhm:' || :NEW.yhm,
v_sqlerrm,
to_char(sysdate, 'yyyyMMddhh24miss'));
end;
----异常处理表结构
-- Create table
create table XT_ERRLOG
(
YWXTMC VARCHAR2(100),
YWXTBM VARCHAR2(100),
CWZDXX VARCHAR2(500),
CWSJ VARCHAR2(1000),
GXBJ VARCHAR2(22)
)
tablespace ZFDXC
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 448
next 1
minextents 1
maxextents unlimited
);
-- Add comments to the table
comment on table XT_ERRLOG
is '系统错误日志表';
-- Add comments to the columns
comment on column XT_ERRLOG.YWXTMC
is '业务系统名称(例:数据中心)';
comment on column XT_ERRLOG.YWXTBM
is '业务系统表名(例:ZYDMB)';
comment on column XT_ERRLOG.CWZDXX
is '显示会导致报错的字段(例如: XH:200010,BJDM:,ZYDM:5200)';
comment on column XT_ERRLOG.CWSJ
is '错误时间(例:YYYYMMDDHH24MISS)';
comment on column XT_ERRLOG.GXBJ
is '更新标记U/I';
Oracle数据库之触发器(二)的更多相关文章
- ORACLE数据库常用查询二
ORACLE数据库常用查询 1.查看表空间对应数据文件情况: SQL MB,AUTOEXTENSIBLE FROM DBA_DATA_FILES; TABLESPACE_NAME FILE_NAME ...
- oracle数据库之触发器
触发器是许多关系数据库系统都提供的一项技术.在 ORACLE 系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的 PL/SQL 块. 一. 触发器类型 触发器在数据库里以独立的对象存储,它与 ...
- 教师信息管理系统(方式一:数据库为oracle数据库;方式二:存储在文件中)
方式一: 运行截图 数据库的sql语句: /*Navicat Oracle Data TransferOracle Client Version : 12.1.0.2.0 Source Server ...
- Oracle数据库之触发器(一)
触发器trigger是数据库提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发.比如当对一个表进行操作(in ...
- Oracle 数据库基础学习 (二) 学习小例子:创建一个表,记录商品买卖的情况
运行环境:Oracle database 11g + PL/SQL Developer ex: --创建一个表 create table plspl_test_product( --加入not n ...
- Oracle数据库配置方式二--使用Net Manager配置数据库
在Oracle安装配置中使用Net Configuration配置了数据库,今天给大家介绍第二种配置方式,Net Manager配置. 先找到我们的Net Manager的快捷方式,如下面截图
- Oracle数据库基本操作(二) —— 视图、序列、索引、同义词
一.视图(Views)与 同义词 1.视图:实际上是对查询结果集的封装,视图本身不存储任何数据,所有的数据都存放在原来的表中; 在逻辑上可以把视图看作是一张表 2.作用: 封装查询语句,简化复杂的查询 ...
- Oracle数据库学习(二):Oracle Linux下oracle、ogg的挂载与参数配置
准备工作:打开虚拟机端的Oracle Linux Server 6.9的系统,然后使用root用户登录.打开终端界面,输入ifconfig -a查看IP地址. 然后在本地打开XShell软件使用以下命 ...
- Oracle数据库学习(二)
2.用SQL进行多表查询 (1)无条件多表查询 笛卡尔集:总记录数=table1记录数×table2记录数 select * from table1, table2 (2)等值连接 内连接:selec ...
随机推荐
- Python笔记(十三)_os模块和os.path模块
os模块中关于文件/目录常用的函数使用方法 getcwd() 返回当前工作目录 chdir(path) 改变工作目录 listdir(path='.') 列举指定目录中的文件名('.'表示当前目录,' ...
- 关于public private protected访问修饰符
这个似乎都是老生常谈了,特别是找工作第一轮笔试的时候很爱考这些,再罗列一次,特别要注意继承的情况: 默认状态:即是不加修饰符的时候,所谓的default状态,在类内部可以被访问,在相同的包下面 ...
- Google File System 论文阅读笔记
核心目标:Google File System是一个面向密集应用的,可伸缩的大规模分布式文件系统.GFS运行在廉价的设备上,提供给了灾难冗余的能力,为大量客户机提供了高性能的服务. 1.一系列前提 G ...
- Go语言格式化字符串
%s: 普通字符串 %q: 引号包含字符串 %x, %o, %b: 十六进制,8进制,2进制 %t: bool值 %d decimal integer %v any value in a natura ...
- 【洛谷p2089】 烤鸡
烤鸡[题目链接] 感觉我超废 关于算法:有很多很多算法吧,但自我感觉最重要的是递归的算法: SOLUTION: 首先忍不住要吐槽这个神仙数据: 嗯???定睛一看,它这数据范围莫不是白瞎了,因为每种配料 ...
- 怎么区分PV、IV、UV以及网站统计名词解释(pv、曝光、点击)
PV(Page View)访问量,即页面访问量,每打开一次页面PV计数+1,刷新页面也是. IV(Internet Protocol)访问量指独立IP访问数,计算是以一个独立的IP在一个计算时段内访问 ...
- Activiti6.0 java项目框架 spring5 SSM 工作流引擎 审批流程
工作流模块----------------------------------------------------------------------------------------------- ...
- 独立成分分析(Independent Component Analysis)
ICA是一种用于在统计数据中寻找隐藏的因素或者成分的方法.ICA是一种广泛用于盲缘分离的(BBS)方法,用于揭示随机变量或者信号中隐藏的信息.ICA被用于从混合信号中提取独立的信号信息.ICA在20世 ...
- 2019-9-2-win10-uwp-兴趣线
title author date CreateTime categories win10 uwp 兴趣线 lindexi 2019-09-02 12:57:38 +0800 2018-2-13 17 ...
- 使用logstash同步MongoDB数据到es
input{ mongodb{ codec => "json" uri => 'mongodb://127.0.0.1:27017/kuaibao' placehold ...