在插入/更新PostgreSQL之前触发检查值

时间:2014-03-30 16:46:12

标签: sql postgresql triggers plpgsql

我必须创建一个触发器来更新有产品的数据库。产品有一个到期日期,在插入或更新产品之前,我必须检查expirationDate是否优于当前时间戳。如果是的话我必须定期插入/更新(这是我遇到的问题)。如果不是,我只是简单地忽略它。

这是我写的代码。

CREATE FUNCTION product_expiration_date()
RETURNS trigger AS $BODY$

BEGIN
IF new.expirationDate > CURRENT_TIMESTAMP THEN
    INSERT INTO Product VALUES (new).*; 
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE 'plpgsql';

CREATE TRIGGER verify_expiration_date BEFORE INSERT OR UPDATE ON Product 
FOR EACH ROW EXECUTE PROCEDURE product_expiration_date();

2 个答案:

答案 0 :(得分:6)

当要检查的条件满足并且您希望INSERT / UPDATE发生时,您的触发器函数应返回NEW,否则NULL跳过操作,或者更好,引发特定的异常错误信息。

它不能自己执行它所调用的INSERT,这将由SQL引擎完成,其值为NEW

跳过操作的代码:

IF new.expirationDate > CURRENT_TIMESTAMP THEN
  RETURN NEW;
ELSE 
  RETURN NULL;
END IF;

或者例外:

IF new.expirationDate > CURRENT_TIMESTAMP THEN
  RETURN NEW;
ELSE 
  RAISE EXCEPTION 'Invalid expiration date';
END IF;

请参阅文档中的Overview of Trigger Behavior了解更多信息。

答案 1 :(得分:0)

检查约束

正如我在this article中所述,实现此目标的最简单方法是通过CHECK约束,这是SQL标准功能。

ALTER TABLE Product
ADD CONSTRAINT verify_expiration_date_check
CHECK (expirationDate < CURRENT_TIMESTAMP)

触发功能

您还可以使用BEFORE INSERT or UPDATE触发器,但这在验证规则需要检查多个表而不只是检查触发表的当前表时更合适。

现在,如果您真的想使用触发功能,那么您的情况就是这样

首先,您需要创建触发函数:

CREATE OR REPLACE FUNCTION product_expiration_date()
  RETURNS TRIGGER AS $$
BEGIN
  IF NEW.expirationDate > CURRENT_TIMESTAMP
  THEN
    RAISE EXCEPTION 'Product [id:%] expired!',
    NEW.id;
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

请注意,如果RAISE大于当前时间戳,我们将使用expirationDate引发异常。

现在,您需要将此触发器函数传递给INSERT和UPDATE触发器:

CREATE TRIGGER verify_expiration_date 
BEFORE INSERT OR UPDATE ON Product 
FOR EACH ROW EXECUTE PROCEDURE product_expiration_date();

尽管您可以使用触发函数,但使用CHECK约束要容易得多。有关PostgreSQL触发函数的更多详细信息,请查看this article