我可以阻止Oracle 11g上的触发器内的插入吗?

时间:2014-06-15 20:39:43

标签: sql oracle triggers insert oracle11g

所以,我想要做的是在条件满足时阻止插入。在这种情况下,我正在开发一个简单的图书馆数据库系统,如果某个人已经借了2本书仍然没有返回,我也不想允许某人借书。他们中的任何一个。

我需要通过触发来做到这一点,有可能吗?另外,我想知道我是否可以像我一样提供对WHEN子句的查询。

CREATE OR REPLACE TRIGGER trigger_borrowing_limit
BEFORE INSERT ON Borrowing
REFERENCING NEW ROW AS NROW
FOR EACH ROW
WHEN SELECT COUNT(*) FROM Borrowing WHERE RETURN_DATE IS NULL AND NROW.ID = Borrowing.ID > 2
BEGIN
?
END

1 个答案:

答案 0 :(得分:1)

您无法为WHEN子句提供查询。从Oracle 11 docs(搜索" WHEN(条件)"到达页面后):

  

WHEN(条件)的限制

     
      
  • 如果指定此子句,则还必须指定FOR EACH ROW。

  •   
  • 条件不能包含子查询或PL / SQL表达式(例如,调用用户定义的函数)。

  •   

至于防止行插入,Mihai的评论是要走的路。您的前端可以捕获异常,如果它的错误编号-20101(根据Mihai的例子),您将知道该人已经有两本书。请注意,某些驱动程序会报告异常编号的绝对值,因此到达您的错误编号可能为20101


附录:后续问题询问如何应用"两本书"逻辑,因为它对WHEN子句无效。

答案是删除WHEN子句并将逻辑放入触发器主体。请注意,我通常会使用标准NEW来引用新行,因此我的答案没有REFERENCING NEW AS NROW

CREATE OR REPLACE TRIGGER trigger_borrowing_limit
  BEFORE INSERT ON Borrowing
DECLARE
  booksOut NUMBER;
BEGIN
  SELECT COUNT(*) INTO booksOut
    FROM Borrowing
    WHERE RETURN_DATE IS NULL AND NEW.ID = Borrowing.ID;
  IF booksOut > 2 THEN
    -- Next line courtesy of Mihai's comment under the question
    raise_application_error(-20101, 'You already borrowed 2 books');
  END IF;
END;