【问题标题】:SQL Before Trigger Not Working触发器之前的 SQL 不起作用
【发布时间】:2015-01-30 15:58:17
【问题描述】:

我正在学习 oracle 并尝试实现前触发器。我想我的代码是正确的,但是一旦我运行插入语句,触发器就不会被调用或使用,但该行仍然插入到表中。谁能看到我做错了什么或知道为什么触发器不起作用?

这是我正在使用的触发器

create or replace
TRIGGER DAY_CHECK BEFORE
  INSERT ON AD_SLOT FOR EACH ROW DECLARE p_day AD_SLOT.DAY_OF_WEEK%TYPE;
  NOTVALID EXCEPTION;
  BEGIN
    IF p_day IN ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday') THEN
      DBMS_OUTPUT.PUT_LINE('VALID DAY');
    ELSE
      RAISE NOTVALID;
    END IF;
 EXCEPTION
 WHEN NOTVALID THEN
   DBMS_OUTPUT.PUT_LINE('NOT A VALID DAY');
   RAISE;
 END;

这是我正在测试的插入语句,它应该引发异常,因为日期无效

 insert into ad_slot values (78955, 'testday', 'ER', 'House', 'Taken', 7654321, '05=FEB-2014 21:00:00');

使用的测试用例

INSERT INTO ad_slot (DAY_OF_WEEK) VALUES ('unwanted day');  

【问题讨论】:

  • 你永远不会给p_day赋值。另外,您不能在触发器中使用commit 或回滚`。
  • 如何将其分配给用户输入的值?
  • 或者像'select day_of_week into p_day from ad_slot'这样的工作吗?
  • 您可以使用new 访问受触发器影响的行。这一切都记录在手册中:docs.oracle.com/cd/E11882_01/appdev.112/e25519/…
  • 不再需要使用关键字new

标签: oracle plsql triggers


【解决方案1】:

您需要将RAISE 放在EXCEPTION 块中,以免INSERT 在不需要的工作日工作。否则,无论如何都会插入该行。

SQL> CREATE TABLE ad_slot(day_of_week VARCHAR2(20));

Table created.

SQL> CREATE OR REPLACE TRIGGER DAY_CHECK BEFORE
  2    INSERT ON AD_SLOT FOR EACH ROW DECLARE p_day AD_SLOT.DAY_OF_WEEK%TYPE;
  3    NOTVALID EXCEPTION;
  4    BEGIN
  5      IF p_day IN ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday') THEN
  6        DBMS_OUTPUT.PUT_LINE('VALID DAY');
  7      ELSE
  8        RAISE NOTVALID;
  9      END IF;
 10    EXCEPTION
 11    WHEN NOTVALID THEN
 12      DBMS_OUTPUT.PUT_LINE('NOT A VALID DAY');
 13      RAISE;
 14    END;
 15  /

Trigger created.

SQL>
SQL> INSERT INTO ad_slot VALUES ('unwanted day');
NOT A VALID DAY
INSERT INTO ad_slot VALUES ('unwanted day')
            *
ERROR at line 1:
ORA-06510: PL/SQL: unhandled user-defined exception
ORA-06512: at "LALIT.DAY_CHECK", line 12
ORA-04088: error during execution of trigger 'LALIT.DAY_CHECK'


SQL>

【讨论】:

  • 感谢 lalit 的回复,但是当我尝试运行此代码时,我收到错误“ORA-06512:在“DT2113A.DAY_CHECK”,第 11 行 ORA-04088:执行触发器 'DT2113A 期间出错.DAY_CHECK''
  • 命令中从第 254 行开始的错误:插入 ad_slot 值(78955、'Monday'、'ER'、'House'、'Taken'、7654321、'05=FEB-2014 21:00 :00') 错误报告:SQL Error: ORA-20001: Program duration is not long enough ORA-06512: at "DT2113A.DAY_CHECK", line 11 ORA-04088: error during execution of trigger 'DT2113A.DAY_CHECK'
  • 您的触发器没有变化,只是删除了提交和回滚,并在异常块中添加了 RAISE。您是否像我一样尝试使用单个插入?
  • 是的,我尝试了您建议的插入,但只是插入了值并且触发器没有停止它
  • 不可能,如果您看到我的回答,RAISE 将由于触发代码中引发未处理的异常而停止插入行。我给了你一个应该可以工作的测试用例。你能像我在回答中那样复制粘贴吗?使用 SQL*Plus 发布您的测试用例,编辑您的问题并粘贴它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
相关资源
最近更新 更多