what:
•触发器是当特定事件出现时自动执行的存储过程
•特定事件可以是执行更新的DML语句和DDL语句
why:
触发器的功能:
–自动生成数据
–自定义复杂的安全权限
–提供审计和日志记录
–启用复杂的业务逻辑
触发器由三个部分组成
•触发器语句(事件)
–定义激活触发器的 DML 事件和 DDL 事件
•触发器限制
–执行触发器的条件,该条件必须为真才能激活触发器
•触发器操作(主体)
–包含一些 SQL 语句和代码,它们在发出了触发器语句且触发限制的值为真时运行
how
创建后置触发器
--------------创建触发器,在删除学生表记录触发---------------------
create or replace trigger student_trigger after--后置触发器 delete--删除操作 on student--作用的表名称 for each row -- 行级触发器,影响一行触发一次,如果不写,语句触发器 -- 执行一条语句不管影响多少行只触发一次 --pl/sql语句块 begin --old指旧的记录行对象,获取被行的所有字段值,new指新的记录行对象 dbms_output.put_line('学生记录【'||:old.id ||'】被删除');
end;
select * from student order by id;
delete from student where id <=5; commit;
测试代码
select * from student order by id;
delete from student where id <=5; commit;
创建后置触发器
-------创建前置触发器,对学生记录新增,修改、删除操作之后进行触发---------------------------------- create or replace trigger stu_trigger after insert or update or delete on student
for each row begin --学生记录新增 if inserting then dbms_output.put_line('学生记录【'||:new.name||'】新增成功'); --修改 elsif updating then dbms_output.put_line('学生记录【'||:old.id||'】由旧密码 '||:old.password||'改成新密码;【'||:new.password||'】');
--删除 elsif deleting then dbms_output.put_line('学生记录【'||:old.id||'】删除成功'); end if; end;
测试代码
insert into student(id,name,username,password,sex,age,birthday,create_time) values(1,'李四','lisi','123456',1,20,to_date('2001-10-10','yyyy-mm-dd'),sysdate);
update student set password ='6666666' where id in(1,11); commit;
delete from student where id <=10; commit; select * from student order by id;
select count(*) from student
课堂练习
---创建触发器,前置触发器,只能在11:00-12:00之间新增,修改,删除表数据
create or replace trigger stu_trigger1 before insert or update or delete on student for each row begin if to_char(sysdate,'hh24') !=12 then raise_application_error(-20001,'学生表记录只能在12点到13点之间操作'); end if;
end;
触发器的几个操作
--禁用触发器 alter trigger stu_trigger1 disable; --删除触发器1= drop trigger stu_trigger1; --启用触发器
alter trigger stu_trigger enable;
create or replace view view_student as --创建视图 select id,name,username,password from student order by id;
select * from view_student ;
---修改表数据 update student set password ='6666666' where id in(11,12); commit;
--修改视图数据 update view_student set password ='1234' where id in(11,12); commit;
--创建instead of 触发器,对视图数据进行修改,针对于包含来自多个变得字段的视图数据修改
create or replace trigger view_emp_trigger instead of --视图触发器,只作用在视图上 insert or update or delete on view_emp --视图名称,包含来自多个表的字段 for each row begin if inserting then dbms_output.put_line('新增操作'); elsif updating then
update departments d set d.department_name =:new.dept_name where d.department_id=( select e.department_id from employees e where e.employee_id = :old.id);
elsif deleting then dbms_output.put_line('删除操作'); end if; end;
select * from departments;
-----模式触发器,主要用来ddl语句中,创建,修改,删除对象是触发 create or replace trigger obj_trigger after--后置触发器 drop--删除对象 on schema --作用在模式上,当前用户 begin dbms_output.put_line('当前用户'||ora_dict_obj_owner||'对象名称:'||ORA_DICT_OBJ_NAME||',对象类型:'||ora_dict_obj_type||' ,删除时间:'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
end;
drop table student_bak20210812;
create table student_bak20210806( id number, name varchar(10) );
create index idx_test_name on test(name); drop index idx_test_name;
--------------创建触发器,在删除学生表记录触发---------------------
create or replace trigger student_trigger after--后置触发器 delete--删除操作 on student--作用的表名称 for each row -- 行级触发器,影响一行触发一次,如果不写,语句触发器 -- 执行一条语句不管影响多少行指触发一次 --pl/sql语句块 begin --old指旧的记录行对象,获取被行的所有字段值,new指新的记录行对象 dbms_output.put_line('学生记录【'||:old.id ||'】被删除');
end;
select * from student order by id;
delete from student where id <=5; commit;
-------创建前置触发器,对学生记录新增,修改、删除操作之后进行触发---------------------------------- create or replace trigger stu_trigger after insert or update or delete on student
for each row begin --学生记录新增 if inserting then dbms_output.put_line('学生记录【'||:new.name||'】新增成功'); --修改 elsif updating then dbms_output.put_line('学生记录【'||:old.id||'】由旧密码 '||:old.password||'改成新密码;【'||:new.password||'】');
--删除 elsif deleting then dbms_output.put_line('学生记录【'||:old.id||'】删除成功'); end if; end;
insert into student(id,name,username,password,sex,age,birthday,create_time) values(1,'李四','lisi','123456',1,20,to_date('2001-10-10','yyyy-mm-dd'),sysdate);
update student set password ='6666666' where id in(1,11); commit;
delete from student where id <=10; commit; select * from student order by id;
select count(*) from student
---创建触发器,前置触发器,只能在11:00-12:00之间新增,修改,删除表数据 create or replace trigger stu_trigger1 before insert or update or delete on student for each row begin if to_char(sysdate,'hh24') !=12 then raise_application_error(-20001,'学生表记录只能在12点到13点之间操作'); end if;
end;
select to_char(sysdate,'hh12') from dual;
-----模式触发器,主要用来ddl语句中,创建,修改,删除对象是触发 create or replace trigger obj_trigger after--后置触发器 drop--删除对象 on schema --作用在模式上,当前用户 begin dbms_output.put_line('当前用户'||ora_dict_obj_owner||'对象名称:'||ORA_DICT_OBJ_NAME||',对象类型:'||ora_dict_obj_type||' ,删除时间:'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));
end;
drop table student_bak20210812;
create table student_bak20210806( id number, name varchar(10) );
create index idx_test_name on test(name); drop index idx_test_name;
---使用触发器,给员工涨工资,工资的更新值必须大于旧的值 create or replace trigger add_emp_salary before update on employees for each row begin if :old.salary> :new.salary then raise_application_error(-20005,'给员工涨工资,工资的更新值必须大于旧的值'); end if; end;
update employees e set e.salary = e.salary +10 where e.employee_id=100;
select * from employees e where e.employee_id=100 ;
--使用触发器,修改学生性别,必须是1或者0,否则提示错误
create or replace trigger sex_xg_stu before update on student for each row begin if :new.sex !=0 and :new.sex !=1 then
raise_application_error(-20007,'修改学生性别,必须是1或者0'); end if; end;
---创建表test和备份test_bak ,当对表新增,修改,删除数据时,同步更新test_bak表,使用触发器实现
drop trigger test_back_trigger;
create or replace trigger test_back_trigger after insert or update or delete on test for each row begin if inserting then insert into test_back values(:new.name,:new.age,:new.sex);
dbms_output.put_line('新增操作');
elsif updating then update test_back t set t.age = :new.age ,t.sex=:new.sex where t.name = :old.name; elsif deleting then delete from test_back t where t.name=:old.name; dbms_output.put_line('删除操作'); end if; end;
try { //1.加载驱动类 Class.forName("oracle.jdbc.driver.OracleDriver"); //2.获取其数据库连接对象 Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "jsd2107", "jsd2107"); //3.获取数据库sql操作对象 PreparedStatement pst = con.prepareStatement("select * from student where id <=20 order by id"); //4.执行sql操作,获取执行结果集 ResultSet rs = pst.executeQuery(); //5.处理结果集,逐行读取记录数 while(rs.next()){//判断结果集中是否有下一行数据,有的话返回true,否则返回false //数据库类型和java类型对比 /**数据库 java * number java.long.Integer * varchar2 java.long.string * date java.sql.Date * timestamp java.sql.Timestamp */ System.out.println("编号:"+rs.getInt("id")+ "姓名:"+rs.getString("name")+ "生日:"+rs.getDate("birthday")+ "创建时间:"+rs.getTimestamp("create_time")); } //6.关闭结果集对象 rs.close(); //7.关闭sql操作对象 pst.close(); //8.关闭数据库连接 con.close(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); }