所以,我想要做的是在条件满足时阻止插入。在这种情况下,我正在开发一个简单的图书馆数据库系统,如果某个人已经借了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
答案 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;