简单的AIU触发器不起作用

时间:2014-03-14 15:49:30

标签: firebird

此触发器是否正确写入?我希望它可以防止金额或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值的数据时,它没有反应。

1 个答案:

答案 0 :(得分:3)

您的触发器正在将字符串(CHAR'INVPOS.AMOUNT''0.00''INVPOS.PRICENET''0.00'进行比较。这些比较的结果总是错误的,因此不会引起异常。

您显然想要比较列的(新)值。使用触发器时,您可以使用NEW上下文变量(具有表的所有列)和带有OLD上下文变量的旧值来检索新值。

我想你想要这个条件:

IF(NEW.AMOUNT = '0.00' or NEW.PRICENET = '0.00')

或者,如果这些值为DOUBLE PRECISIONNUMERICDECIMAL

IF(NEW.AMOUNT = 0.00 or NEW.PRICENET = 0.00)

那就是说:您应该在CHECKAMOUNT列上使用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/上获得)。