Oracle principles: DML triggers and database triggers

One, DML trigger

The function of the trigger is to automatically execute the content in the execution block when an event occurs.

Triggers can act on tables or views, and can specify specific program segments to be executed before, during, or after insert or update or delete operations.

CREATE [OR REPLACE] TRIGGER triggername 
  BEFORE/INSTEAD OF/AFTER           ---选择事件触发(前,时,后)执行 PL/SQL代码块
  [INSERT [OR] UPDATE [OR] DELETE]  ---当执行 插入 、更新、删除前触发
  ON tblname_or_viewname            ---确认作用的表或者视图
  [Referencing {OLD [AS] old / NEW [AS] new }] 
  [FOR EACH ROW]           --指定行级触发器,不指定就是表级触发器
  [WHEN (condition)]       --当符合condition的条件满足时触发
DECLARE
  -- local variables here
BEGIN
  ;--PL/SQL block

END triggername ;

Deleted in sqlserver is a temporary table for storing old information that will be updated and deleted, corresponding to Oracle: old, Inserted is a temporary table for storing new information that is about to be inserted and updated, corresponding to Oracle: new. :new and :old represent a row of data to be operated on instead of representing the entire data set, so [FOR EACH ROW] is usually added to indicate row triggers when using these two. Among them, the operation of update is actually to put the data in: old first, then delete and then put the new data in: new and insert it into the database.

Since: old is stored, the old data is about to be deleted or changed, so it is meaningless to update old. After it is triggered after the operation has been completed, it is meaningless to operate on the new data at this time. When it is after, the record of :new cannot be modified.

For a multi-table view, it is possible to change the key to retain the contents of the table . You can also perform DML operations on single-table view j

Table-level triggers are executed only once when the table or view event is triggered. When row-level triggers are triggered on a table or view event, the content of the program block will be executed once every time a row of data is affected

Rollback, commit and DDL statements cannot be used in DML triggers.

Create a new practice table department_tbl:

Create the following triggers to compare the effects

create view VW_department_tbl as select * from department_tbl;
--------insert视图VW_department_tbl时,给每行数据Leaders 默认值'BOSS'----
create or replace trigger departInsertDefault2
  Instead of insert   --替换原有的insert语句,且Instead Of 只能作用于视图, WHEN不能用于 INSTEAD OF
  on VW_department_tbl
  FOR EACH ROW
declare
begin
  if  :new.leaders is null then
    insert into department_tbl values(:new.department,:new.all_salary,'BOSS');
  else 
     insert into department_tbl values(:new.department,:new.all_salary,:new.leaders);
  end if;
end departInsertDefault2 ;
drop trigger departInsertDefault2;
-----------------------------------
--------insert表department_tbl时,给每行数据Leaders 默认值'BOSS'----
create or replace trigger departInsertDefault1
  before insert 
  on department_tbl 
  FOR EACH ROW
  WHEN (new.leaders is null
)declare
  
begin 
  :new.leaders :='BOSS';
end departInsertDefault1 ;
drop trigger departInsertDefault1;

Execute on trigger 2

Execute on trigger 1

New trigger 3,

create or replace procedure dep_insert(dep in department_tbl.department%type ,sal in department_tbl.all_salary%type) 
is  PRAGMA AUTONOMOUS_TRANSACTION;  --自主事物处理
begin
 insert into department_tbl values(dep,sal,'BOSS');
  --update department_tbl set leaders='BOSS' where leaders is null and department = dep;  --取不到还未提交的数据
commit;
end dep_insert;
/
create or replace trigger departInsertDefault3
  after insert        --after 无法修改基表的数据,需要自主事物处理的存储过程配合,且新数据属于未提交状态
  on department_tbl
  FOR EACH ROW
  WHEN (new.leaders is null)
  
declare
  v_data department_tbl%rowtype;
begin  
 --update department_tbl set leaders='BOSS' where leaders is null and department = :new.department;  --无法执行
  dep_insert( :new.department,:new.all_salary);
  
end departInsertDefault3 ;
drop trigger departInsertDefault3;

carried out

In short, if you want to modify the data, it is recommended to use before, after is suitable for data verification, and Instead of can only be used for views.

update example:

create or replace trigger departInsertDefault4
  before update        
  on department_tbl
  FOR EACH ROW
  when (old.department = new.department)
declare
begin  
    :new.all_salary := :new.all_salary+:old.all_salary;
end departInsertDefault4 ;
/
--drop trigger departInsertDefault4;

truncate table department_tbl;
insert into department_tbl(department,all_salary) values('部门1',2000);
insert into department_tbl(department,all_salary,leaders) values('部门1',2000,'BOSS');
insert into department_tbl(department,all_salary,leaders) values('部门2',3000,'雇佣者1');
update department_tbl set department = '部门999' where Leaders is not null;
update department_tbl set Leaders = 'boss' where Leaders is not null;
commit;
select * from department_tbl;

The final execution result:

Two, mode (DDL) trigger


Create table obj_tbl(
obj_name varchar2(30),
obj_type varchar2(20),
obj_date Date
)

create or replace trigger obj_trigger 
 after Create --alter drop
on SCHEMA
BEGIN
  insert into  obj_tbl values( ora_dict_obj_name,ora_dict_obj_type,SYSDATE);
END;
/

ora_client_ip_address Used to return the client's IP address
ora_database_name Used to return the current database name
ora_des_encrypted_password Used to return DES encrypted user password
ora_dict_obj_name Used to return the database object name corresponding to the DDL operation
ora_dict_obj_name_list(name_list_ OUT ora_name_list_t) Used to return a list of modified object names in a word event
ora_dict_obj_owner Used to return the owner name of the object corresponding to the DDL operation.
ora_dict_obj_ower_list(ower_list OUT ora_name_list_t) Used to return the list of owners of the object that was modified in the event
ora_dict_obj_type Used to return the type of database object corresponding to the DDL operation.
ora_grantee(user_list OUT ora_name_list_t) Used to return the event authorizer during authorization.
ora_instance_num Used to return the course number.
ora_is_alter_column(column_name IN VARCHAR2) Used to detect whether a specific column has been modified
ora_is_creating_nested_table Used to detect whether a nested table is being built
ora_is_drop_column(column_name IN VARCHAR2) Used to detect whether a specific column is deleted
ora_is_servererror(error_number) Used to detect whether a specific Oracle error was returned.
ora_login_user Used to return the login user name
ora_sysevent  Used to return the name of the system time that triggered the trigger.

 

 

Three, database-level triggers

 

----数据库启动触发器-----
create or replace trigger db_trigger 
after startup on database
begin 
  insert into  obj_tbl values( ora_sysevent,null,SYSDATE);
end;
/
----数据库用户登录触发器-----
create or replace trigger user_trigger 
after logon on database
begin 
  insert into  obj_tbl values( ora_login_user,ora_client_ip_address,SYSDATE);
end;
/ 

Fourth, the operation of the trigger

alter tigger tiggername ENABLE/DISABLE open and close the trigger 

select * from dba_triggers/user_triggers query trigger information

Guess you like

Origin blog.csdn.net/superSmart_Dong/article/details/107093957