44.4. PL/Tcl 中的全局数据

有时,将某些全局数据保存在两次调用函数之间或在不同函数之间共享会很有用。这在 PL/Tcl 中很容易完成,但是必须理解一些限制。

出于安全原因,PL/Tcl 在单独的 Tcl 解释器中为该角色执行由任何一个 SQL 角色调用的函数。这样可以防止一个用户意外或恶意干扰另一用户的 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的示例。