Postgresql

只讀 postgres 表,觸發器除外

  • June 5, 2016

假設以下情況:

我有一張product_stock桌子和一張stock_transaction_log桌子。目前,每當產品庫存增加/減少時,我都會更新product_stock表增加或減少數量,並在事務日誌表中插入一個條目以進行審計。這是在應用程式碼中完成的。

我正在考慮product_stock通過事務日誌表上的觸發器來更改表的更新(而不是直接在我的應用程式碼中進行),但我想補充一點,product_stock表永遠不會直接更新,並且只有觸發器被授權更新它。

無論如何在postgresql中這樣做(目前使用9.1)

Ziggy 提出的解決方案將起作用,但如果您不想通過創建特權使用者來執行觸發器而深入,您可以嘗試另一種解決方案:在product_stock表上創建一個驗證觸發器,檢查是否更新來自stock_transaction_log觸發器。為此,我們可以創建一個臨時表作為“全域變數”。

CREATE OR REPLACE FUNCTION validate_product_stock() RETURNS trigger AS $$
DECLARE
   count_ int;
BEGIN
   BEGIN
       SELECT COUNT(1) INTO count_ FROM __inside_stl_trigger WHERE note = 'inside trigger';
   EXCEPTION WHEN undefined_table THEN
       count_ := 0;
   END;

   IF count_ = 0 THEN
       RAISE EXCEPTION 'This table is automatically updated by stock_transaction_log'
   END IF;

   RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER validate_product_stock_trigger
   BEFORE INSERT OR UPDATE ON product_stock
   FOR EACH ROW
   EXECUTE PROCEDURE validate_product_stock();

CREATE OR REPLACE FUNCTION update_product_stock() RETURNS trigger AS $$
BEGIN
   CREATE TEMPORARY TABLE __inside_stl_trigger (note text NOT NULL);
   INSERT INTO __inside_stl_trigger (note) VALUES ('inside trigger');

   -- Update the product_stock table here

   DROP TABLE __inside_stl_trigger;
   RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_product_stock_trigger
   BEFORE INSERT OR UPDATE ON stock_transaction_log
   FOR EACH ROW
   EXECUTE PROCEDURE update_product_stock();

顯然,可以手動創建該臨時表,在其上插入一行並進行更新,但至少您會使它變得更難。

引用自:https://dba.stackexchange.com/questions/133707