使用触发器通知自己有关更改的行是没有意义的。如果你在表格中插入新的行,那么你有关于它们的所有信息。为什么不喜欢的东西以下的块,而不是一个触发器:
create table reviews as select 0 as rid, 0 as userid, 0 as score, 0 as pid from dual where 1=0;
create table users as select 101 as userid, cast('nobody' as varchar2(100)) as uname from dual;
create table products as select 1001 as pid, cast('prod 1001' as varchar2(100)) as pname from dual;
<<my>>declare newreview reviews%rowtype; uname users.uname%type; pname products.pname%type; begin
insert into reviews values(1,101,10,1001) returning rid,userid,score,pid into newreview;
select uname, pname into my.uname, my.pname
from users u natural join products p
where u.userid = newreview.userid and p.pid = newreview.pid
;
dbms_output.put_line('user: '||my.uname||' entered a new review for Product: '||my.pname||' with a review score of: '||newreview.score);
end;
/
输出:user: nobody entered a new review for Product: prod 1001 with a review score of: 10
为了告知你应该使用DBMS_ALERT事件(交易)或DBMS_PIPE(非交易)封装另一个会话。 dbms_alert的一个例子:
create or replace trigger new_review_trig after insert on reviews for each row
begin
dbms_alert.signal('new_review_alert', 'signal on last rid='||:new.rid);
end;
/
在另一个会话(新窗口,工作表,sqlplus或其他)中运行以下块。它会被阻止,直到登记的信号到达:
<<observer>>declare message varchar2(400); status integer; uname users.uname%type; pname products.pname%type; score reviews.score%type;
begin
dbms_alert.register('new_review_alert');
dbms_alert.waitone('new_review_alert', observer.message, observer.status);
if status != 0 then raise_application_error(-20001, 'observer: wait on new_review_alert error'); end if;
select uname, pname, score into observer.uname, observer.pname, observer.score
from reviews join users using(userid) join products using (pid)
where rid = regexp_substr(observer.message, '\w+\s?rid=(\d+)', 1,1,null,1)
;
dbms_output.put_line('observer: new_review_alert for user='||observer.uname||',product='||observer.pname||': score='||observer.score);
end;
/
现在,在您的会话:
insert into reviews values(2, 101,7,1001);
commit; --no alerting before commit
的另一个(观察员)会议将与输出完成:
observer: new_review_alert for user=nobody,product=prod 1001: score=7
使用dbms_output意味着只有执行插入的用户才会看到该消息 - 然后仅当他们启用了输出时 - 这有点没有意义。它只对调试非常有用/安全。你也总是会得到一个或多个行,所以不知道查询的要点是什么;当你查询触发器所反对的表时,你可能会遇到一个变异表错误 - 尽管这看起来并不是必须的。 –