2014-01-10 74 views
0

我正在爲外部接收記錄csv,然後當我創建或更新postgresql條目時,需要創建一個鏡像只有符號差異的條目。這可以在程序級完成,我很想知道是否可以使用觸發器。 對於我可以找到的示例,它們都以代碼結尾, FOR EACH ROW EXECUTE PROCEDURE foo() 並且通常會處理檢查,使用NEW.additionalfield添加附加信息,或插入另一個表中。如果我以這種方式使用觸發器在同一個表中插入另一行,看起來觸發器將再次觸發,並且創建變爲遞歸。 任何方法來解決這個問題?如何在postgresql中創建/更新一行時觸發創建/更新另一行記錄

回答

0

當觸發器處理,拇指規則是:

  1. 如果它改變了當前行,基於一些業務規則或其他(例如添加額外的信息或處理計算字段),它屬於BEFORE觸發器。

  2. 如果它在單獨的表中有一個或多個行有副作用,它屬於AFTER觸發器。

  3. 如果它運行在完整性檢查任何表,沒有其他的內置約束(檢查,獨特的鍵,外鍵,排除等),可以照顧的,它屬於一個CONSTRAINT [後]觸發。

  4. 如果對同一表中的一個或多個其他副作用,你應該重新審視你的模式,你的代碼流,或兩者兼而有之。

關於最後一點,其實有解決方法的Postgres的,如想獲得一個鎖或檢查XMIN VS事務的XID,以避免在遞歸情況下陷入困境。最近的版本另外引入了pg_trigger_depth()。但我仍然建議反對它。

請注意,約束觸發器可創建爲deferrable initially deferred。這將延遲限制觸發器,直到交易的最後,而不是緊接在該陳述之後。

您的問題和暱稱暗示您想知道如何在複式簿記應用程序中自動平衡一組行。假設如此,請不要自動創建平衡條目。相反,開始一個事務,單獨輸入每一行,並且有一個(對於每一行,可延遲的最初延遲)約束觸發器從那裏挑選事物,如果有任何不平衡,則拒絕整個批處理。如果你想平衡兩三條以上的路線,那麼這樣做會讓你頭痛不已。

另一個解讀可能是您想要創建審計線索。如果是這樣,則創建其他審計表並在觸發器之後使用它們來填充它們。有多種方式來創建和管理這些審計表。看看slowly changing dimensions。 (Fwiw,類型6,start_endtsrangetstzrange列可以很好地用於審計表,如果您對錶的完整歷史記錄感興趣,包括其與其他審計表的關係歷史記錄。)爲您的應用程序使用「實時」表以保持速度,並在需要歷史報告時使用審計表。

相關問題