受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

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

有时需要在一次函数调用结束后保留某些全局数据,供下一次调用继续使用,或者在不同函数之间共享全局数据。在 PL/Tcl 中这很容易做到,但必须理解其中的一些限制。

出于安全原因,PL/Tcl 会针对每个 SQL 角色,在该角色各自独立的 Tcl 解释器中执行其调用的函数。这样可以防止一个用户无意或恶意地干扰另一用户的 PL/Tcl 函数行为。每个这样的解释器都为任何global 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的用法。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。