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
books表
ISBNTitleAuthor1Author2Author3
72223855Oracle 9i38  
authors表字段:id,first_name,last_name
authors表
IDFirst_nameLast_name
38RobetFreeman

 books_authors 视图

books_authors 视图
ISBNTitleFirst_nameLast_name
72223855Oracle 9iRobetFreeman

 

  用表 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;

 

Books
ISBNTitleAuthor1Author2Author3
72223855Oracle 9i381000 

 

authors
IDFirst_nameSecond_name
38RobetFreeman
1000EsetrtElegmen

 

books_authors
ISBNTitleFirst_nameLast_name
72223855Oracle 9iRobetFreeman
72223855Oracle 9iEsetrtElegmen

 

 

转载于:https://www.cnblogs.com/qianwen/p/3766504.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值