为什么我的触发器在插入行之前被触发,即使在触发器声明中指定了[AFTER]?

时间:2017-12-10 15:13:20

标签: oracle plsql triggers

问题:在SQL触发器的输出中混淆(代码发布在下面)

SQL> insert into STUDENT VALUES('NAME');

Output: 
<<Trigger Executed>>
1 row created.

为了便于阅读和理解,我创建了一个简单易懂的触发器和表格:

执行程序ON: [ORACLE 10g SQL命令行]

SQL:> start F:/FILE.SQL

FILE.SQL 包含(代码下方):

set serveroutput ON;

-- <<DROPING ANY TABLE IF ALREADY EXIST>>
DROP TABLE STUDENT ;

CREATE TABLE STUDENT  
(
    sname varchar2(20) 
)
/

CREATE OR REPLACE TRIGGER MYTRIGGER
AFTER INSERT ON STUDENT 
FOR EACH ROW 
BEGIN
    dbms_output.put_line('<<Trigger Executed>> '); 
END;
/
insert into STUDENT values('Myname');

问题:因为在插入值后立即执行触发器。所以,如果我理解正确的理论,输出应该是:

1 row created.
<<Trigger Executed.>>

而不是

<<Trigger Executed.>>
1 row created.

从逻辑上说这是正确的。

尝试:我在触发器声明中尝试了BEFOREAFTER以获得所需的输出,但每次都得到相同的结果。

我知道触发器是如何工作的,我只是对执行的顺序感到困惑。

2 个答案:

答案 0 :(得分:4)

无论触发器在交易窗口中发生了什么。事实上,触发器在触发语句中是原子的:也就是说,如果任何触发器失败,则整个语句都会失败。

quote = "Wheresoever you go, go with all your heart" word = "" quote=quote.split(' ') for i in quote: if(i[0].lower()>='h'): word=word+i.upper()+' ' print(word) 只是语句已完成的SQL * Plus消息。在原子操作完成之前无法显示。这就是您的触发器输出在SQL * Plus消息之前的原因

答案 1 :(得分:2)

会发生什么

  1. 插入新行。
  2. 触发触发并打印"<<Trigger Executed.>>"
  3. 命令终止,SQL * Plus打印"1 row created"
  4. 即,在插入行并且已经运行触发器之后打印“创建1行”。如果要在触发器触发时查看是否已插入行,请改为打印学生姓名。像

    这样的东西
    CREATE OR REPLACE TRIGGER MYTRIGGER
        AFTER INSERT ON STUDENT 
        FOR EACH ROW
    BEGIN
       dbms_output.put_line('<<Trigger executed, student = ' || :new.sname || ' >>');
    END;
    

    输出现在应该是

    <<Trigger executed, student = Myname >>  
    1 row created.