触发器是指被隐含执行的存储过程。当发生特定事件时,oracle会自动执行触发器的相应代码,触发器由触发事件,触发条件和触发操作三部分组成。
dml触发器触发顺序
对于单行数据而言,无论是语句触发器还是行触发器,触发器代码实际只被执行一次。dml触发器在单行数据上的触发顺序:before语句触发器、before行触发器、dml操作、after行触发器、after语句触发器。
例如:
建立before语句触发器(在sql语句执行之前调用该触发器)
create or replace trigger insert_aaa
before insert or update or delete on aaa
begin
insert into bbb values(1,'aaa');
end;
当在触发器中同时包含多个触发事件的时候,为了区分具体的事件可以使用条件谓词
inserting 当触发时间是insert操作时,返回true
updating 当触发时间是update操作时,返回true
deleting 当触发时间是delete操作时,返回true
例如:
create or replace trigger insert_aaa
before insert or update or delete on aaa
begin
if inserting then
insert into bbb values(1,'aaa');
elsif updating then
insert into bbb values(2,'bbb');
elsif deleting then
insert into bbb values(3,'ccc');
end if;
end;
建立after语句触发器(在sql语句执行之后调用该触发器)
create or replace trigger insert_aaa
after insert or update or delete on aaa
begin
if inserting then
insert into bbb values(1,'aaa');
elsif updating then
insert into bbb values(2,'bbb');
elsif deleting then
insert into bbb values(3,'ccc');
end if;
end;
行触发器是指执行dml操作时,每作用一行就触发一次触发器。行级触发器的触发时间同样分为before和after建立行级before触发器
例如:
create or replace trigger aaa_emp
before update of a_sal on aaa
for each row
begin
if :new.a_sal < :old.a_sal then
insert into bbb values('aaa',123);
else
insert into bbb values('bbb',321);
end if;
end;
建立行级after触发器
例如:
create or replace trigger aaa_emp
after update of a_sal on aaa
for each row
begin
if :new.a_sal < :old.a_sal then
insert into bbb values('aaa',123);
else
insert into bbb values('bbb',321);
end if;
end;
行级触发器可以使用when子句来限制触发条件,只有在满足了when子句的限制条件,触发器才会被调用。
例如:
create or replace trigger aaa_emp
after update of a_sal on aaa
for each row
when (old.a_name = 'aaa')
begin
if :new.a_sal < :old.a_sal then
insert into bbb values('aaa',123);
else
insert into bbb values('bbb',321);
end if;
end;
注意:当编写dml触发器时,触发器代码不能从触发器所对应的基表中读取数据。可以在declare部分中定义变量
create or replace function 函数名
(
参数1 in 类型,
参数2 in 类型
)
return 返回类型
as
局部变量 类型(长度);
begin
语句;
return 返回值;
end;
要点:
1、只有局部变量有长度
2、只有参数用逗号,其它都是;号
3、赋值方式
select ... into 变量 from ...;
变量 := ...
4、最后要return
-------------------------------
--根据日期返回年份
create or replace function f_get_year
(
rq in date
)
return char
as
str char;
begin
null;
return null;
end;
--在程序窗口中编写:
create or replace function f_get_year
(
rq in date
)
return char
as
str char(4);
begin
select to_char(rq,'yyyy') into str from dual;
return str;
end;
--测试:
select f_get_year(sysdate) from dual;
select stu_id, s_name, c_id, s_birthday, f_get_year(s_birthday) as x
from t_stu
--根据学生的姓名,返回第一个字,如果姓名有2个字,加上**,有3个字,加***。
create or replace function f_get_name(
--字段类型:表.字段%type
stu_name in t_stu.s_name%type
)
return varchar2
as
str varchar2(10);
len number(2);
begin
--根据姓名,返回第一个字,如果姓名有2个字,加上**,有3个字,加***。
str := substr(stu_name, 1, 1);
len := length(rtrim(stu_name));
if(len=2)then
str := str||'**';
elsif (len=3)then
str := str||'***';
end if;
return str;
end;
--测试:
select stu_id, s_name,f_get_name(s_name) as x
from t_stu
--函数与存储过程区别:函数没有增删改语句,不能修改数据。