Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql:在函数上触发以使其可更新,如可更新视图_Sql_Postgresql_Triggers - Fatal编程技术网

Postgresql:在函数上触发以使其可更新,如可更新视图

Postgresql:在函数上触发以使其可更新,如可更新视图,sql,postgresql,triggers,Sql,Postgresql,Triggers,我已经在PostgreSQL中创建了一个函数,该函数在几个表上工作,并根据传递的参数组装结果。它工作得很好,从客户端的角度来看,它看起来像一个带有附加参数的普通表(也就是说,它可以像通常的select查询一样进行查询) 为了一直隐藏有关底层数据的信息,我还想创建一种写入表的方法。我想我应该创建一个触发器,它执行一个基本上更新相关底层表的函数。但是,我无法在函数上创建触发器。除了表之外,还有什么方法可以在其他任何东西上创建触发器吗?我也在考虑使用视图(我相信可以在视图上创建触发器),但是我需要将函

我已经在PostgreSQL中创建了一个函数,该函数在几个表上工作,并根据传递的参数组装结果。它工作得很好,从客户端的角度来看,它看起来像一个带有附加参数的普通表(也就是说,它可以像通常的select查询一样进行查询)


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

您似乎想要在函数上创建一个等价的可更新视图,您可以
插入
,函数的
更新
删除
。这是不可能的

如果您提供的是类似于接口的函数,那么也可以提供用于修改数据的函数

或者,将函数转换为视图。允许它们使用
WHERE
子句限制视图,而不是将参数传递给函数。然后使用视图触发器(PostgreSQL 9.1及以上版本)或规则(PostgreSQL 9.0及以下版本,如果可能,请勿在较新版本上使用)在视图上启用
插入
更新
删除
。见和。规则很复杂,所以请按首选项使用视图触发器

PostgreSQL非常擅长将过滤器向下推到视图中,因此
从一些视图中选择*,其中一些列=4
通常不会扫描整个视图,然后对其进行过滤。它将把
WHERE
子句“推”到视图的查询中并执行该查询。因此,如果您的视图是
SELECT*FROM some\u table WHERE NOT\u archive
PostgreSQL实际上会执行与
SELECT*FROM some\u table WHERE NOT\u archive)和some col=4相当的
。因此,在查询视图时,如果只查询几行,而不是所有行,您可以而且通常会得到完全不同的查询计划

仅在视图中包装函数不会很好地工作,除非它是
稳定的
SQL函数,而不是
不可变的
(因此可以内联)。最好从函数中提取SQL并基于相同的SQL创建视图,而不是基于函数本身


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

这太遗憾了。我想在INSERT、UPDATE、DELETE中使用相同的名称“table name”,并使用这些查询的语法。如果我使用函数来处理这些函数,我需要使用SELECT来执行这些函数,对吗?@Max这是正确的,在PostgreSQL中运行函数需要
SELECT
,因为PostgreSQL没有真正的存储过程,可以通过
调用调用
。如果您正在使用这些API,那么可以使用ODBC/JDBC调用转义语法,例如JDBC
{call my_func(arguments)}
。无论如何,通过函数强制执行所有操作都是笨拙而缓慢的;如果你的函数的参数正被用来建立一个<>代码> 子句,我会认真考虑一个可更新的视图。@ Max详细解释了一下。谢谢克雷格。我认为将函数转换为视图是相当困难的,因为它使用参数来调用一些其他函数(我理解在视图中是不可能的)。当然,我可以尝试内联所有使用的方法,但这将非常混乱。我真的不确定最好的选择是什么…我可能会创建一个代理视图,用于插入、更新和删除它们,并在它们上创建一些触发器。其他选项似乎太复杂了,特别是因为SELECT已经运行良好。对于将来的问题,如果您能显示代码和您的PostgreSQL版本,我们将不胜感激。例如,在本例中,您可能会显示函数定义、如何使用它以及希望如何使用它。