【问题标题】:Creating trigger which throws an exception on insert创建在插入时引发异常的触发器
【发布时间】:2014-01-20 11:22:49
【问题描述】:

各位程序员大家好,祝大家新年快乐!

寒假我的大学任务很少,其中之一是在桌子上创建触发器:

PERSON(ID, Name, Surname, Age);

当用户插入了无效 ID 的行时,触发器应该通知用户。有效性标准是 ID 长度为 11 位。

我试着写这样的解决方案:

CREATE OR REPLACE TRIGGER person_id_trigg
AFTER INSERT
ON person
DECLARE
  idNew VARCHAR(50);
  lengthException EXCEPTION;
BEGIN
  SELECT id INTO idNew FROM INSERTED;
  IF LENGTH(idNew) <> 11 THEN
  RAISE lengthException;
  END IF;
  EXCEPTION
  WHEN lengthException THEN
  dbms_output.put_line('ID for new person is INVALID. It must be 11 digits long!'); 
END;

然后我意识到INSERTED只存在于sqlserver中而不存在于oracle中。

你会建议我做些什么来解决这个问题?

提前致谢!

【问题讨论】:

  • 使用BEFORE INSERT,而不是AFTER INSERT。使用FOR EACH ROW 子句。不要执行任何查询,只需检查new.id。阅读此链接了解详细信息,那里有很多示例:docs.oracle.com/cd/B28359_01/appdev.111/b28370/…
  • 感谢您的输入,显然我需要阅读此文档以了解触发器。

标签: sql oracle plsql triggers


【解决方案1】:

您是否要引发异常(这会阻止插入成功)?或者您是否希望插入成功并将一个字符串写入dbms_output 缓冲区,该缓冲区可能存在也可能不存在,并且可能会或可能不会显示给运行插入的人?

在任何一种情况下,您都希望这是一个行级触发器,而不是语句级触发器,因此您需要添加 for each row 子句。

CREATE OR REPLACE TRIGGER person_id_trigg
  AFTER INSERT
  ON person
  FOR EACH ROW

如果你想引发异常

BEGIN
  IF( length( :new.id ) <> 11 )
  THEN
    RAISE_APPLICATION_ERROR( -20001, 
                             'The new ID value must have a length of 11' );
  END IF;
END;

如果您想打印输出但允许insert 成功

BEGIN
  IF( length( :new.id ) <> 11 )
  THEN
    dbms_output.put_line( 'The new ID value must have a length of 11' );
  END IF;
END;

当然,在现实中,你永远不会使用触发器来处理这类事情。在现实世界中,您将使用约束。

【讨论】:

  • 感谢您的回答,但是当我尝试编译它时,我收到此错误:错误报告 - ORA-04082:表级触发器中不允许新或旧引用 04082。00000 -“新或旧引用不是表级触发器中允许” *原因:触发器正在访问表触发器中的“新”或“旧”值。 *行动:删除任何新的或旧的引用。
  • @Roff - 我错过了您已将触发器声明为语句级触发器而不是行级触发器的事实。将其添加到我的答案中。
  • 感谢您的帮助,我清楚地误解了触发器的用法。现在它工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-09
  • 2020-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多