简体   繁体   English

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

[英]Can I block an insert inside a trigger on Oracle 11g?

So, what I want to do is to block an insert if the condition is met. 所以,我想要做的是在条件满足时阻止插入。 In this case, I'm developing a simple library database system and I don't want to allow someone to be able to borrow a book if that certain person has already borrowed 2 books and still hasn't returned any of them. 在这种情况下,我正在开发一个简单的图书馆数据库系统,如果某个人已经借了2本书并且还没有退回任何一本书,我不想让某人能够借书。

I need to do this via trigger, is it possible? 我需要通过触发来做到这一点,有可能吗? Also, I'd like to know if I can supply a query into the WHEN clause like I did. 另外,我想知道我是否可以像我一样提供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

You can't supply a query for the WHEN clause. 您无法提供WHEN子句的查询。 From the Oracle 11 docs (search for "WHEN (condition)" once you get to the page): Oracle 11文档 (一旦到达页面搜索“WHEN(condition)”):

Restrictions on WHEN (condition) 对WHEN(条件)的限制

  • If you specify this clause, then you must also specify FOR EACH ROW. 如果指定此子句,则还必须指定FOR EACH ROW。

  • The condition cannot include a subquery or a PL/SQL expression (for example, an invocation of a user-defined function). 条件不能包含子查询或PL / SQL表达式(例如,调用用户定义的函数)。

As for preventing the row insert, the comment from Mihai is the way to go. 至于防止行插入,Mihai的评论是要走的路。 Your front end can catch the exception, and if it's error number -20101 (per Mihai's example) you'll know that the person already has two books out. 你的前端可以捕获异常,如果它是错误号-20101 (根据Mihai的例子),你会知道这个人已经有两本书了。 Note that some drivers will report the absolute value of the exception number, so the error number that reaches you may be 20101 . 请注意,某些驱动程序将报告异常编号的绝对值,因此到达您的错误编号可能是20101


Addendum: a followup question asked how to apply the "two books out" logic since it's not valid for the WHEN clause. 附录:后续问题询问如何应用“两本书”逻辑,因为它对WHEN条款无效。

The answer is to drop the WHEN clause and put the logic into the trigger body. 答案是删除WHEN子句并将逻辑放入触发器主体。 Note that I normally stick with the standard NEW for referencing the new row, so my answer doesn't have the REFERENCING NEW AS NROW : 请注意,我通常坚持使用标准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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM