如何在 PostgreSQL 中创建临时函数?

Posted

技术标签:

【中文标题】如何在 PostgreSQL 中创建临时函数?【英文标题】:How to create a temporary function in PostgreSQL? 【发布时间】:2011-06-26 19:29:40 【问题描述】:

我必须在数据库中执行一个循环。这只是一次性要求。 执行完函数后,我现在要删除函数。

有没有什么好的方法来创建临时/一次性函数?

【问题讨论】:

【参考方案1】:

smart trick in @crowmagnumb's answer 的一些附加说明

该函数必须始终schema-qualified,即使pg_tempsearch_path中(就像默认情况下一样),according to Tom Lane以防止木马:李>
CREATE FUNCTION pg_temp.f_inc(int)
  RETURNS int AS 'SELECT $1 + 1' LANGUAGE sql IMMUTABLE;

SELECT pg_temp.f_inc(42);
f_inc
-----
43

在临时架构中创建的函数仅在 同一会话 内可见(就像临时表一样)。它对所有其他会话不可见(即使对于相同的角色)。您可以SET ROLE 之后以不同角色在同一会话中访问该函数。

您甚至可以基于这个“临时”函数创建一个函数索引:

CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));

从而在非临时表上使用临时函数创建普通索引。这样的索引对所有会话都是可见的,但仍然只对创建会话有效。查询计划器将不使用函数索引,其中表达式在查询中不重复。还是有点龌龊的把戏。会话关闭时它将自动删除 - 作为依赖对象。这种感觉根本不应该被允许……


如果您只需要重复执行一个函数并且只需要 SQL,请考虑使用 prepared statement。它的行为很像一个在会话结束时终止的临时 SQL 函数。但是,这不是相同的东西,并且只能与EXECUTE一起使用,而不是嵌套在另一个查询中。示例:

PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;

呼叫:

EXECUTE upd_tbl(123, 'foo_name');

详情:

Split given string and prepare case statement

【讨论】:

【参考方案2】:

如果您使用的是 9.0 版,则可以使用新的 DO 语句来执行此操作:

http://www.postgresql.org/docs/current/static/sql-do.html

对于以前的版本,您需要创建函数、调用它并再次删除它。

【讨论】:

... 它对于在终端上编写脚本很有用,但你不能再次调用它,就像“匿名函数”(或 lambda)一样,所以 DO 语句不如“临时函数”有用"。 @PeterKrauss:如果你想再次调用它,你需要创建一个真正的函数。 当然是我的 a_hourse :-) 我只是展示了实现“临时”的理论路径...这就是为什么对于主要问题,更好的答案(可能使用 PostgreSQL)是 @987654325 @。我不明白为什么(!?)今天,2014 年,像Lua、SQL DML 这样简单而快速的例子不能提供lambda functions(!)。 另外,DO 语句不能有输入参数,也不能返回结果,这与函数相反。 如果不返回,我们是否应该称其为“函数”?【参考方案3】:

我需要知道如何在我正在编写的脚本中多次使用。原来你可以使用 pg_temp 模式创建一个临时函数。这是为您的连接按需创建的模式,是存储临时表的位置。当您的连接关闭或过期时,此架构将被删除。事实证明,如果您在此模式上创建一个函数,该模式将自动创建。因此,

create function pg_temp.testfunc() returns text as 
$$ select 'hello'::text $$ language sql;

只要您的连接仍然存在,该功能就会一直存在。无需调用 drop 命令。

【讨论】:

【参考方案4】:

对于临时程序,cursors 还不错。然而,它们对于产品使用来说效率太低了。

它们将让您轻松循环数据库中的 sql 结果。

【讨论】:

为什么你认为游标在 PostgreSQL 中效率低? 游标在循环时保持数据库连接。具有数百个长时间运行的游标的网页将缺乏连接并使网站/数据库陷入瘫痪。

以上是关于如何在 PostgreSQL 中创建临时函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Play 框架中的演变在 PostgreSQL 中创建函数?

在 Postgresql 中创建一个具有多列作为参数的函数

在 Postgresql 中创建一个不返回复合值的函数

在 lua 中创建一个临时文件

在 FUNCTION 中创建临时表 [重复]

sql 在Postgresql中创建truncate_tables函数。