94

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

有没有创建临时/一次性功能的好方法?

4

4 回答 4

136

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

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

只要您的连接仍然存在,它将是一个持续存在的功能。无需调用 drop 命令。

于 2012-04-02T18:12:34.230 回答
70

@crowmagnumb 的回答中对聪明技巧的一些附加说明

  • 根据 Tom Lane的说法,该函数必须始终是模式限定的,即使pg_temp是在search_path(就像默认情况下一样),以防止特洛伊木马:
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

  • 你甚至可以基于这个“temp”函数创建一个函数索引:

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

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


如果您只需要重复执行一个函数并且只需要 SQL,请考虑使用准备好的语句。它的行为很像一个在会话结束时终止的临时 SQL 函数。但是,不是同一件事,只能与 一起使用EXECUTE,不能嵌套在另一个查询中。例子:

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

称呼:

EXECUTE upd_tbl(123, 'foo_name');

细节:

于 2015-06-28T02:04:46.340 回答
31

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

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

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

于 2011-02-14T09:40:41.453 回答
-6

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

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

于 2011-02-14T09:41:12.270 回答