2012-09-02 90 views
0

我是PostgreSql的新手,我使用的是8.3版本。我需要創建一個函數來檢查表是否有特定的觸發器。如果觸發器存在,我需要刪除它。如何從函數執行動態查詢(創建觸發器)?

如下面給出我生成下拉查詢:「 '|| var_TriggersRecord 「

var_DropTriggerSqlPart =降觸發' '上triggerName」 ||「的SchemaName 」||「' || var_Record」。 「。」'|| var_Record。「TableName」||'「;';

- (其中所有'var_'都是具有所需數據的變量)。

執行var_DropTriggerSqlPart;

但我沒有看到觸發器丟失。有人能讓我知道我在這裏做錯了嗎?

回答

0

我想我找到了答案。我將「執行」更改爲「執行」,並將功能變爲「易失性」而非「穩定」。

0

這裏有幾個要點。

首先,你是正確的,EXECUTE是正確的方式來做到這一點。如果你正在創建一個觸發器,雖然有一些事情要記住(我們做了很多這樣的事情)。

最大的問題是像這樣的效用語句沒有查詢計劃,所以不能被參數化。當然,您創建一個字符串並將其作爲SQL執行。這具有所有問題,包括SQL注入的可能性。如果你的函數是SECURITY DEFINER,那麼你可以通過存儲過程中的sql注入來提升權限。

這可以通過很好地瞭解兩個函數來解決:quote_ident()和quote_literal()。

在你上面的例子,我會建議其更改爲:

var_DropTriggerSqlPart = 'drop trigger "' || 
    quote_ident(var_TriggersRecord."triggerName") || '" on "' || 
    quote_ident(var_Record."SchemaName") || '"."' || 
    quote_ident(var_Record."TableName") || '";'; 

在LedgerSMB我們做了很多的UDF的工具語句,並要處理這個問題。通常我們也將大部分功能放在一起,以便於審查/審覈。

+0

非常感謝您的意見。 – Arun