问题报告 纠错本页面

41.4. PL/Tcl里的全局量

有时候在两次过程函数调用或者不同的函数之间保存一些全局数据是非常有用的。 在PL/Tcl里实现这个目标相当容易,但是这里有一些限制必须熟悉。

由于安全原因,PL/Tcl通过一个在单独的Tcl解释器里的SQL角色执行函数调用。 通过有另外一个用户的PL/Tcl函数行为的用户阻止了偶然的或恶意的干扰。 每个这样的干扰对于任意的"全局" Tcl变量将有它自己的值。 因此,当且仅当他们通过同一个SQL角色执行时,两个PL/Tcl函数才分享相同的全局变量。 在一个多个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例子里显示。