2012-08-03 18 views
0

我在視圖上創建了一個ON DELETE規則,該規則將OLD選擇到臨時表中,然後調用一個函數,該函數使用舊。該規則在運行SELECT INTO TEMPORARY TABLE之前刪除臨時表,以防在執行SELECT dropTempTable()時在會話期間多次調用該規則。這一切都正常工作,除非沒有東西需要刪除,例如當有與「李四」的名稱沒有記錄運行下面的查詢:即使規則沒有行作用,Postgres也會創建SELECTed INTO表

DELETE FROM myview WHERE name = 'John Doe'; 

在這種情況下,臨時表是由策劃者,準備創建它正在使用,即使它不會是,但我的dropTempTable()語句永遠不會被調用,所以我第二次在我的視圖上執行DELETE時,它失敗了,因爲臨時表已經存在。任何建議如何解決這個問題將不勝感激。我意識到使用觸發器可以更好地解決這個例子,但是爲了本文的目的我已經簡化了它,並且觸發器將不適用於我的特定問題。

筆者認爲:

CREATE VIEW myview  
AS SELECT * FROM mytable 

我的規則:

CREATE RULE myview_delete 
AS ON DELETE TO myview 
DO INSTEAD (
    SELECT dropTempTable(); 
    SELECT OLD INTO TEMPORARY TABLE myTempTable; 
    SELECT myDeleteFunction(); 
); 

我刪除表功能:

CREATE FUNCTION dropTempTable() 
RETURNS void AS $$ 
BEGIN 
    DROP TABLE IF EXISTS myTempTable; 
END; 
$$ LANGUAGE plpgsql; 
+1

「*觸發器不適用於我的特殊問題*」。爲什麼? – 2012-08-03 08:38:27

+2

我會**從不**刪除並在規則內創建表。決不。海事組織的重寫規則在這種情況下不會太困難;基本上是從存在的temptable中刪除(select * from realtable where keyfield = temptable.keyfield and realtable.keyfield = OLD.keyfield);'順便說一句:你是否意識到這條規則是根據語句調用的? – wildplasser 2012-08-03 08:54:25

+0

感謝您的回覆。我不能使用觸發器,因爲我有幾個傳統客戶端正在與Postgres進行通信,而且我需要一段時間才能替換它們。同時,爲了繼續支持傳統客戶端,我們正在遷移到新的後端,我使用Postgres的內置語言來編寫函數,這些語言橋接Postgres和新的後端。在某些情況下,實際上沒有數據會被寫入Postgres表中,觸發器將適用於此表。當然,我有SELECT,INSERT和UPDATE規則支持這一點。我知道這聽起來很亂,但我有幾個選項,它的工作 – user1545610 2012-08-04 02:41:14

回答

0

我結束了移動我打電話給dropTempTable功能了刪除規則,並添加一條EXCEPTION語句進入SELECT規則,如下所示:

我刪除表功能:

CREATE FUNCTION dropTempTable() 
RETURNS void AS $$ 
BEGIN 
    DROP TABLE IF EXISTS myTempTable; 
EXCEPTION 
    WHEN OTHERS THEN 
END; 
$$ LANGUAGE plpgsql; 

這是一個黑客攻擊的一位,但它的作品。

相關問題