SIGNAL SQLSTATE内部触发器失败

时间:2015-02-01 18:11:49

标签: oracle triggers sql-update

我有一个包含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;

1 个答案:

答案 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来通知调用者任何事情,因为你不知道调用者是在查看缓冲区还是做任何事情。