1

我在 PostgreSQL 中创建了一个函数,该函数适用于几个表,并根据传递的参数组合结果。它工作得很好,从客户的角度来看,它看起来像一个带有附加参数的普通表(即,它可以像通常的选择查询一样被查询)。

为了继续隐藏有关基础数据的信息,我还想创建一种写入表的方法。我想我会创建一个触发器来执行一个基本上会更新相关基础表的函数。但是,我无法在函数上创建触发器。除了表之外,还有什么方法可以在其他任何东西上创建触发器吗?我也在考虑使用视图(因为我相信可以在视图上创建触发器),但是我需要将函数更改为不适合的视图,因为我无法传入一个参数。

4

1 回答 1

3

您似乎想要在函数上创建等效的可更新视图,您可以在其中INSERTUPDATEDELETE函数上。这是不可能的。

如果您要提供类似函数的接口,请同时提供用于数据修改的函数。

或者,将您的函数转换为视图。允许他们使用WHERE子句来限制视图,而不是将参数传递给函数。然后使用视图触发器(PostgreSQL 9.1 及更高版本)或规则(PostgreSQL 9.0 及更低版本,如果可能,请勿在较新版本上使用)启用INSERT,UPDATEDELETE视图。见CREATE TRIGGERCREATE RULE。规则很棘手,因此请根据偏好使用视图触发器。

PostgreSQL 非常聪明地将过滤器下推到视图中,因此SELECT * FROM some_view WHERE some_col = 4通常不会扫描整个视图然后过滤它。它会将子句“推送”WHERE到视图的查询中并执行它。因此,如果您的观点是SELECT * FROM some_table WHERE NOT is_archivedPostgreSQL 实际上会执行相当于SELECT * FROM some_table WHERE (NOT is_archived) AND some_col = 4. 因此,在查询仅几行与所有行的视图时,您可以并且经常确实获得完全不同的查询计划。在我不久前写的一篇文章中有一个例子

仅将您的函数包装在视图中不会很好地工作,除非它是一个 SQL 函数,STABLE而不是IMMUTABLE(因此它可以被内联)。您最好从函数中提取 SQL 并基于相同的 SQL 创建视图,而不是基于函数自身。

如果您的函数参数未在简单WHERE子句中使用,那么它会变得更加复杂,因为无法像在函数中那样将参数传递到视图中。您可以在参数的所有可能值上创建一个视图,然后对其进行过滤,但是如果 Pg seq 扫描该视图,这可能会导致非常糟糕的性能。在这些更复杂的情况下,我想提供一个函数调用接口来进行修改。

于 2012-10-29T01:22:59.493 回答