我有一个包含4列的Product表。 2列是价格。如果ListPrice列更新为低于指定的量(StandardCost * 1.2),则更新应该失败并且旧的ListPrice应该保留。我试图使用SIGNAL SQLSTATE错误来防止在满足条件时发生更新。
我一直在梳理谷歌并尝试了各种语法变化,但在编译我的触发器时我一直遇到以下错误 - “PLS-00103 - 在遇到以下任何一种情况时遇到符号'SQLSTATE':= =, (@%“
非常感谢任何帮助。
CREATE OR REPLACE TRIGGER Product_Price_Check
BEFORE INSERT OR UPDATE OF ListPrice ON Product
FOR EACH ROW
DECLARE
min_price NUMBER(10, 2);
new_price NUMBER(10, 2);
BEGIN
min_price := (:OLD.StandardCost*1.2);
new_price := (:NEW.ListPrice);
IF (new_price < min_price) THEN
-- Rolls back an explicit or implicit transaction to the beginning of the transaction
dbms_output.put_line('the price can’t be below ' || TO_CHAR(min_price));
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insert/update failed';
END IF;
END;
答案 0 :(得分:0)
正如mustaccio所说,你将MySQL语法与Oracle触发器混合在一起。你想要raise_application_error
:
BEGIN
IF :NEW.ListPrice < (:OLD.StandardCost*1.2) THEN
raise_application_error(-20001,
'the price can’t be below ' || TO_CHAR(:OLD.StandardCost*1.2));
END IF;
END;
/
这不会回滚事务,只会回滚更新语句。调用者将收到异常并决定如何处理它 - 是否重试,回滚或提交已经进行的任何其他更改。
这假设旧的标准成本不能为空。您可能还想为to_char()
指定格式模型。
同样不要依赖dbms_output
来通知调用者任何事情,因为你不知道调用者是在查看缓冲区还是做任何事情。