您似乎想要在函数上创建等效的可更新视图,您可以在其中INSERT
或UPDATE
在DELETE
函数上。这是不可能的。
如果您要提供类似函数的接口,请同时提供用于数据修改的函数。
或者,将您的函数转换为视图。允许他们使用WHERE
子句来限制视图,而不是将参数传递给函数。然后使用视图触发器(PostgreSQL 9.1 及更高版本)或规则(PostgreSQL 9.0 及更低版本,如果可能,请勿在较新版本上使用)启用INSERT
,UPDATE
和DELETE
视图。见CREATE TRIGGER
和CREATE RULE
。规则很棘手,因此请根据偏好使用视图触发器。
PostgreSQL 非常聪明地将过滤器下推到视图中,因此SELECT * FROM some_view WHERE some_col = 4
通常不会扫描整个视图然后过滤它。它会将子句“推送”WHERE
到视图的查询中并执行它。因此,如果您的观点是SELECT * FROM some_table WHERE NOT is_archived
PostgreSQL 实际上会执行相当于SELECT * FROM some_table WHERE (NOT is_archived) AND some_col = 4
. 因此,在查询仅几行与所有行的视图时,您可以并且经常确实获得完全不同的查询计划。在我不久前写的一篇文章中有一个例子。
仅将您的函数包装在视图中不会很好地工作,除非它是一个 SQL 函数,STABLE
而不是IMMUTABLE
(因此它可以被内联)。您最好从函数中提取 SQL 并基于相同的 SQL 创建视图,而不是基于函数自身。
如果您的函数参数未在简单WHERE
子句中使用,那么它会变得更加复杂,因为无法像在函数中那样将参数传递到视图中。您可以在参数的所有可能值上创建一个视图,然后对其进行过滤,但是如果 Pg seq 扫描该视图,这可能会导致非常糟糕的性能。在这些更复杂的情况下,我想提供一个函数调用接口来进行修改。