0

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

我正在生成如下所示的删除查询:

var_DropTriggerSqlPart = '删除触发器 "' || var_TriggersRecord."triggerName" || '" on "' || var_Record."SchemaName" || '"."' || var_Record."TableName" || '";';

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

执行 var_DropTriggerSqlPart;

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

4

2 回答 2

0

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

于 2012-09-02T18:37:56.430 回答
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 中做了很多实用程序语句,并且必须处理这个问题。通常,我们还将执行此操作的大部分功能放在一起以便于审查/审计。

于 2012-09-03T00:04:38.253 回答