【发布时间】:2011-06-26 19:29:40
【问题描述】:
我必须在数据库中执行一个循环。这只是一次性要求。 执行完函数后,我现在要删除函数。
有没有什么好的方法来创建临时/一次性函数?
【问题讨论】:
标签: sql postgresql sql-function
我必须在数据库中执行一个循环。这只是一次性要求。 执行完函数后,我现在要删除函数。
有没有什么好的方法来创建临时/一次性函数?
【问题讨论】:
标签: sql postgresql sql-function
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');
详情:
【讨论】:
如果您使用的是 9.0 版,则可以使用新的 DO 语句来执行此操作:
http://www.postgresql.org/docs/current/static/sql-do.html
对于以前的版本,您需要创建函数、调用它并再次删除它。
【讨论】:
DO 语句不能有输入参数,也不能返回结果,这与函数相反。
我需要知道如何在我正在编写的脚本中多次使用。原来你可以使用 pg_temp 模式创建一个临时函数。这是为您的连接按需创建的模式,是存储临时表的位置。当您的连接关闭或过期时,此架构将被删除。事实证明,如果您在此模式上创建一个函数,该模式将自动创建。因此,
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
只要您的连接仍然存在,该功能就会一直存在。无需调用 drop 命令。
【讨论】:
对于临时程序,cursors 还不错。然而,它们对于产品使用来说效率太低了。
它们将让您轻松循环数据库中的 sql 结果。
【讨论】: