2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4

42.4. PL/Tcl 中的全局数据 #

有时,在两次函数调用之间保持一些全局数据或在不同函数之间共享全局数据非常有用。这在 PL/Tcl 中很容易实现,但有一些必须理解的限制。

出于安全原因,PL/Tcl 为任何一个 SQL 角色调用的函数执行一个单独的 Tcl 解释器。这可以防止一个用户意外或恶意地干扰另一个用户的 PL/Tcl 函数的行为。每个这样的解释器将拥有自己的一组 全局 Tcl 变量的值。因此,两个 PL/Tcl 函数将共享相同的全局变量,当且仅当它们由同一个 SQL 角色执行时。在同一个会话中通过多个 SQL 角色执行代码的应用程序(通过 SECURITY DEFINER 函数、使用 SET ROLE 等)中,您可能需要采取明确的步骤来确保 PL/Tcl 函数可以共享数据。要做到这一点,请确保应该通信的函数属于同一个用户,并将它们标记为 SECURITY DEFINER。当然,您必须注意此类函数不能被用于执行任何意外的操作。

在一个会话中使用的所有 PL/TclU 函数都在同一个 Tcl 解释器中执行,该解释器当然与用于 PL/Tcl 函数的解释器是分开的。因此,全局数据会在 PL/TclU 函数之间自动共享。这不被视为安全风险,因为所有 PL/TclU 函数都以相同的信任级别执行,即数据库超级用户的级别。

为了帮助保护 PL/Tcl 函数不被意外地相互干扰,一个全局数组通过 upvar 命令提供给每个函数。这个变量的全局名称是函数的内部名称,局部名称是 GD。建议将 GD 用于函数的持久私有数据。仅将常规 Tcl 全局变量用于您特意打算在多个函数之间共享的值。(请注意,GD 数组仅在特定解释器内部是全局的,因此它们不会绕过前面提到的安全限制。)

在下面的 spi_execp 示例中,有一个使用 GD 的示例。

提交更正

如果您在文档中看到任何不正确的内容,与您对特定功能的体验不符,或者需要进一步的澄清,请使用 此表格 报告文档问题。