簡體   English   中英

在 PostgreSQL 上的 INSERT 或 UPDATE 之前檢查給定值的觸發器

[英]Trigger for checking a given value before INSERT or UPDATE on PostgreSQL

我必須創建一個觸發器來更新有產品的數據庫。 產品有一個過期日期,在插入或更新產品之前,我必須檢查 expireDate 是否優於當前時間戳。 如果是,我必須定期進行插入/更新(這是我遇到的問題)。 如果不是,我只是簡單地忽略它。

這是我編寫的代碼。

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();

當要檢查的條件滿足並且您希望 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;

有關更多信息,請參閱文檔中的觸發器行為概述

檢查約束

實現此目標的最簡單方法是通過CHECK約束,這是 SQL 標准功能。

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

觸發功能

您還可以使用BEFORE INSERTBEFORE 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約束要容易得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM