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

发布于 2024-10-17 10:10:23 字数 76 浏览 7 评论 0原文

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

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

I have to execute a loop in database. This is only a one time requirement.
After executing the function, I am dropping the function now.

Is there any good approach for creating temporary / disposable functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无悔心 2024-10-24 10:10:23

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

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

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

I needed to know how to do a many time use in a script I was writing. Turns out you can create a temporary function using the pg_temp schema. This is a schema that is created on demand for your connection and is where temporary tables are stored. When your connection is closed or expires this schema is dropped. Turns out if you create a function on this schema, the schema will be created automatically. Therefore,

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

will be a function that will stick around as long as your connection sticks around. No need to call a drop command.

终止放荡 2024-10-24 10:10:23

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

  • 该函数必须是<始终保持强>模式限定,即使 pg_temp 位于 search_path 中(就像默认情况下一样),根据 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之后,您可以在同一会话中以不同角色的身份访问该功能。

  • 适用于PROCEDURE类似的时尚。

  • 您甚至可以基于此创建函数索引“临时”功能:

     在 tbl 上创建索引 foo_idx (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');

详细信息:

A couple of additional notes to the smart trick in @crowmagnumb's answer:

  • The function must be schema-qualified at all times, even if pg_temp is in the search_path (like it is by default), according to Tom Lane to prevent Trojan horses:
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
  • A function created in the temporary schema is only visible inside the same session (just like temp tables). It's invisible to all other sessions (even for the same role). You can access the function as a different role in the same session after SET ROLE.

  • Works for a PROCEDURE in similar fashion.

  • You could even create a functional index based on this "temp" function:

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

Thereby creating a plain index using a temporary function on a non-temp table. Such an index would be visible to all sessions but still only valid for the creating session. The query planner will not use a functional index, where the expression is not repeated in the query. Still a bit of a dirty trick. It will be dropped automatically when the session is closed - as a depending object. Feels like this should not be allowed at all ...


If you just need to execute a function repeatedly and all you need is SQL, consider a prepared statement instead. It acts much like a temporary SQL function that dies at the end of the session. Not the same thing, though, and can only be used by itself with EXECUTE, not nested inside another query. Example:

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

Call:

EXECUTE upd_tbl(123, 'foo_name');

Details:

绾颜 2024-10-24 10:10:23

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

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

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

If you are using version 9.0, you can do this with the new DO statement:

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

With previous versions, you'll need to create the function, call it, and drop it again.

泅人 2024-10-24 10:10:23

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

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

For ad hock procedures, cursors aren't too bad. They are too inefficient for productino use however.

They will let you easily loop on sql results in the db.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文