触发器 Trigger 作用是监听数据库.
可以监听的事件有三大类
1.数据库事件,监听整个数据库的事件.
STARTUP 数据库启动时触发
SHUTDOWN 在使用NORMAL或IMMEDIATE选项关闭数据库时触发 .
LOGON 当用户连接到数据库会话时触发.
LOGOFF 当用户断开数据库会话时触发.
SERVERERROR 当数据库发生异常时触发.
2.数据库模式定义语言DDL(Data Definition Language)事件,监听数据库对象的事件
CREATE 在创建新对象时触发.
ALTER 修改数据库或数据库对象时触发.
DROP 删除对象时触发.
3.数据操纵语言(DML)事件,监听数据库表或视图的事件
INSERT 在表或视图中插入数据时触发.
UPDATE 修改表或视图中的数据时触发.
DELETE 在删除表或视图中的数据时触发.
select; /*这行无用.仅为了使文本变色*/
create or replace trigger text
text 为触发器名称
before insert or update or delete
-- 触发时间 空格 触发事件
-- 触发时间为如下3种.
-- before 在语句执行前触发.晚于约束.
-- after 在语句执行结束后触发.晚于约束
-- instead of 在语句执行前触发.早于约束. instead of 可用来做详细约束处理.
-- 触发事件为如下5种.
-- insert 增加数据时触发
-- update 修改数据时触发 update of 列名 可以指定哪些列变化时触发.
-- delete 删除数据时触发
-- insert or update 增加或修改数据时触发
-- insert or update or delete 增加或修改或删除数据时触发
on textTable --触发器监听的表或视图
for each row
-- 触发器执行方式
-- for each statement 语句级触发器.一次访问算一次无论修改多少条数据.
-- for each row 行级触发器.修改多少条数据触发多少次.
declare
-- local variables here
--触发器变量与游标声明位置
begin
--触发器方法体执行位置
end text;--触发器名称
因为一个表或视图可以绑定多个触发器.所以触发器之间执行是有先后顺序的.
语句级触发器 > 行级触发器
instead of > before > after
instead of 触发时间的触发器一种事件只能创建一个,before 与 after 可以创建多个.
INSERTING DELETING UPDATING
在IF 语句中使用.可以用来判断当前执行的是什么.
语法:
IF INSERTING THEN
--方法体
ELSEIF DELETING THEN
--方法体
ELSE
--方法体
END IF;
获取数据变量 :OLD 与 :NEW
用来获取触发器触发时变量.
其中 INSERT时 只有 :NEW ;
DELETE 时 只有 :OLD ;
UPDATE 时 有:OLD :NEW
语法:
:NEW.列名
1.变量的声明 赋值 与使用.
变量的声明是在 declare 中声明.使用则在 begin 中.
赋值可以在任意位置赋值.
语法:
declare
--变量声明.
test varchar2(10); --变量名 变量类型
testId number(1);
testvalue varchar(20);
begin
--变量赋值
test := 值;
select id,valeu into testId,testvalue from 表 where 1 = 1
--可以直接查询并赋值.
--变量使用
test
testId
testvalue
end;
2.游标声明与使用.
游标的声明是在 declare 中声明.使用则在 begin 中.
游标的使用方式2种
一for循环遍历获取.
二 使用OPEN打开游标获取其中一条.
需要注意的是.游标在自定义事物下无法获取数据.
语法:
declare
CURSOR testdate is --testdate 游标名
select * from 表 where 1 = 1;--游标查询数据sql语句
testrow testdate%rowtype; --声明一个变量testrow 定义为游标testdate类型
begin
--第一种方式.
FOR testrow IN testdate LOOP --每次循环将数据从游标中提取一行放入到变量里
IF testdate%FOUND THEN --判断有数据为true
testrow.ID --变量可以直接获取对应的列
END IF;
END LOOP;
--第二种方式.
OPEN testdate; --打开这个游标
FETCH testdate --获取其中一行数据放入变量中
INTO testrow;
IF testdate%NOTFOUND THEN --判断没有数据时为true
testrow.ID --变量可以直接获取对应的列
END IF;
CLOSE testdate;
end;
通常情况下触发器的事物是与监听的表共用同一个事物.
当触发器中出现错误.将会回滚触发器以及触发事件的表.
因为触发器与表共用同一个事物.所以在触发器中不能对本表(触发事件的表)进行操作.
但此时想查询本表数据的话.就用到了自定义事物(不推荐使用.建议更改设计)
自定义事物.
在触发器中想对本表进行查询时使用.
语法:
declare --在 declare 中进行定义.
PRAGMA AUTONOMOUS_TRANSACTION;
begin
--方法体
COMMIT;
end;
当触发器出现异常时.通过EXCEPTION可以获取到出现异常的类型
并且可以打印到控制台异常出现时的信息.
EXCEPTION
WHEN no_data_found THEN
dbms_output.put_line(错误的数据);--在控制台打印消息
WHEN OTHERS THEN
dbms_output.put_line();
触发器中还有很多我不会的.需要学习的. ><”