如何从函数执行动态查询(创建触发器)?

时间:2012-09-02 18:12:57

标签: function postgresql triggers dynamicquery

我是PostgreSql的新手,我使用的是8.3版本。我需要创建一个函数来检查表是否具有特定的触发器。如果触发器存在,我需要放弃它。

我正在生成drop查询,如下所示:

var_DropTriggerSqlPart =' drop trigger"' || var_TriggersRecord" triggerName" || '" on"' || var_Record"的SchemaName" || '""' || var_Record"表名" || '&#34 ;;&#39 ;;

- (其中所有' var _'是具有所需数据的变量)。

执行var_DropTriggerSqlPart;

但我没有看到触发器掉线。有人可以让我知道我在这里做错了吗?

2 个答案:

答案 0 :(得分:0)

我想我找到了答案。我将“执行”更改为“执行”并使函数“易失”而不是“稳定”。

答案 1 :(得分: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中做了很多实用程序语句,并且必须处理这个问题。通常,我们还将大多数功能放在一起,以便于审核/审核。