此触发器是否正确写入?我希望它可以防止金额或pricenet为零。这些列定义为具有十进制数据类型的域。
CREATE OR ALTER trigger invpos_biu0 for invpos
active before insert or update position 0
AS
begin
IF('INVPOS.AMOUNT' = '0.00' or 'INVPOS.PRICENET' = '0.00')
THEN exception zero_value;
end
我使用IBExpert是否相关。当我插入具有0值的数据时,它没有反应。
答案 0 :(得分:3)
您的触发器正在将字符串(CHAR
)'INVPOS.AMOUNT'
与'0.00'
和'INVPOS.PRICENET'
与'0.00'
进行比较。这些比较的结果总是错误的,因此不会引起异常。
您显然想要比较列的(新)值。使用触发器时,您可以使用NEW
上下文变量(具有表的所有列)和带有OLD
上下文变量的旧值来检索新值。
我想你想要这个条件:
IF(NEW.AMOUNT = '0.00' or NEW.PRICENET = '0.00')
或者,如果这些值为DOUBLE PRECISION
,NUMERIC
或DECIMAL
:
IF(NEW.AMOUNT = 0.00 or NEW.PRICENET = 0.00)
那就是说:您应该在CHECK
和AMOUNT
列上使用PRICENET
约束,而不是触发器。这比触发器更清晰,更明显。
在Firebird中,您可以使用列和表级别检查约束,例如:
CREATE TABLE INVPOS (
...,
CONSTRAINT CHK_INVPOS_NONZERO CHECK (AMOUNT <> 0 OR PRICENET <> 0)
)
或
CREATE TABLE INVPOS (
...,
AMOUNT DECIMAL(6,2) NOT NULL CHECK (AMOUNT <> 0),
PRICENET DECIMAL(6,2) NOT NULL CHECK (PRICENET <> 0),
...
)
请注意,您还可以命名约束,这样更容易进行错误处理。有关详细信息,请参阅Interbase 6语言参考(可在http://www.firebirdsql.org/en/reference-manuals/上获得)。