有时,让一些全局数据在对同一个函数的两次调用之间保持,或者在 不同函数之间共享,是很有用的。 在 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 数组只在特定解释器内是全局的,因此它们
不能绕过上面提到的安全限制。)
使用 GD 的示例见下文的
spi_execp 例子。