首页 > 代码库 > Instead-of触发器
Instead-of触发器
DML触发器除了执行insert,update或delete操作以外,还要执行触发器主体的命令。
Instead-of触发器会用触发器主体的命令替换相应的DML操作(触发的insert,update,delete都没有执行,仅执行了触发器主体的命令)
Instead-of 触发器常用于管理编写不可更新的视图
1.Instead-of触发器用触发器主体的命令替换相应的DML操作。
现在需要实现:向表student 插入数据时,检查id是否存在于表student中,如存在则进行更新操作,否则就不更新且输出提示信息。
create trigger CheckId insetead of update --替换原来的update as if not exists(select * from student where id=:new.id) begin rollback transaction DBMS_OUTPUT.PUT_LINE(‘要处理记录的学生ID不存在‘); end; else begin update student set first_name=:new.first_name; where id= :new.id; end; end CheckId; / --触发 trigger CheckId update student set first_name=‘David‘ where id=‘12721205‘ --其实没有实现这个update,而是实现了CheckId的主体
2. instead-of触发器常用于管理编写不可更新的视图 ->1.不可更新视图 使用了集合操作运算符(UNION,UNION ALL ,INTERSECT,MINUS) 使用了分组函数(MIN,MAX,SUM,AVG) 使用了GROUP BY ,CONNECT BY ,START WITH 子句 使用了DISTINCT 关键字 使用了连接查询 对于基于上述情况创建的视图,不能对其直接执行DML,但可以在该视图上创建INSTEAD OF触发器来间接执行DML。 ->2. 使用Instead-of触发器解决不可更新视图示例 books表字段:issbn,title,athour_id1,author_id2,author_id3
ISBN | Title | Author1 | Author2 | Author3 |
72223855 | Oracle 9i | 38 |
authors表字段:id,first_name,last_name
ID | First_name | Last_name |
38 | Robet | Freeman |
books_authors 视图
ISBN | Title | First_name | Last_name |
72223855 | Oracle 9i | Robet | Freeman |
用表 books 和author表,创建视图books_authors
create or replace view books_authors as select b.isbn,b.title,a.first_name,a.last_name from books b join authors a on b.authors_id1=a.id or b.authors_id2=a.id or b.authors_id3=a.id;
执行DML会报错(在不可更新视图上不能使用DML)
insert into books_authors(isbn,title,first_name,last_name) vaules(‘72223855‘,‘SQL Cookbook‘,‘Joe‘,‘Blow‘);
解决方案:
用instead-of触发器来实现insert语句的正常操作,即更新两个底层表。
create or replace trigger InsertBooksAuthors instead of insert on books_authors --这个insert 替换了前面的insert,它没有直接更新不可更新视图,而是更新生成它的两个底层表 declare v_book books%rowtype; v_author_id authors.id%type; begin begin select id into v_author_id from authors where first_name= :new.first_name and last_name= :new.last_name; --如果插入的记录(first_name,last_name 在books表中存在,就取出这条记录) exception when no_data_found then insert into authors(id,first_name,last_name) vaules(author_sequence.nextval,:new.first_name,:new.last_name) returning id into v_author_id; --如果不存在则重新插入到authors表 end; select * into v_book from books where isbn= :new.isbn; if v_book.author_id2 is null then update books set author_id2=v_author_id where isbn= :new.isbn; else update books set author_id3=v_author_id where isbn= :new.isbn; end if; end InsertBooksAuthors;
ISBN | Title | Author1 | Author2 | Author3 |
72223855 | Oracle 9i | 38 | 1000 |
ID | First_name | Second_name |
38 | Robet | Freeman |
1000 | Esetrt | Elegmen |
ISBN | Title | First_name | Last_name |
72223855 | Oracle 9i | Robet | Freeman |
72223855 | Oracle 9i | Esetrt | Elegmen |
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。