我必须在数据库中执行循环。这只是一次性要求。 执行该函数后,我现在正在删除该函数。
是否有任何创建临时/一次性功能的好方法?
答案 0 :(得分:86)
我需要知道如何在我写的脚本中多次使用。事实证明,您可以使用pg_temp架构创建临时函数。这是根据您的连接需求创建的模式,也是存储临时表的位置。当您的连接关闭或过期时,将删除此架构。如果在此架构上创建函数,则会自动创建架构。因此,
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
只要你的连接附近就会有一个功能。无需调用drop命令。
答案 1 :(得分:42)
smart trick in @crowmagnumb's answer的几个附加说明:
pg_temp
位于search_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');
详细说明:
答案 2 :(得分:27)
如果您使用的是9.0版,则可以使用新的DO语句执行此操作:
http://www.postgresql.org/docs/current/static/sql-do.html
对于以前的版本,您需要创建该函数,调用它并再次删除它。
答案 3 :(得分:-5)
对于广告诉讼程序,cursors并不算太糟糕。然而,它们对于产品的使用效率太低。
它们可以让你轻松地在db中循环sql结果。