🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 42.7\. 后台PL/Perl ## 42.7.1\. 配置 本节列出影响PL/Perl的配置参数。 `plperl.on_init` (`string`) 指定当Perl触发器第一次初始化时执行Perl代码,在这之前是专业为了`plperl`或 `plperlu`使用的。当这段代码执行时SPI函数是不适用的。如果代码因错误而失败, 那么它将退出解释器的初始化,并且传播错误到调用的查询,导致当前事务或子事务退出。 Perl代码限制为单个字符串。更长的代码可以放入一个模块,并且由`on_init`字符串加载。例子: ``` plperl.on_init = 'require "plperlinit.pl"' plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;' ``` 任何由`plperl.on_init`直接或非直接加载的模块,都将适用于`plperl`使用。 这可能会创建一个安全风险。要查看哪个模块被加载了可以使用: ``` DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; ``` 如果plperl库包含在[shared_preload_libraries](#calibre_link-576)里面,那么初始化将在postmaster中发生, 这种情况下要额外考虑postmaster不稳定的风险。利用这一特性的首要原因是Perl模块通过`plperl.on_init` 加载需要在postmaster启动的情况下,并且在个人的数据库会话中不会有额外开销加载,立即可用。然而, 请记住,额外开销只是在第一次Perl解释器被数据库会话使用的时候避免, 也就是PL/PerlU或PL/Perl是调用PL/Perl函数的第一个SQL角色。 在一个数据库会话中创建的任何额外的Perl解释器必须重新执行`plperl.on_init`。同样,在Windows上, 从预加载中不会有任何节省,因为在postmaster进程中创建的Perl解释器不会传播到子进程。 这个postmaster只能在`postgresql.conf`文件或服务器命令行中设置。 `plperl.on_plperl_init` (`string`) `plperl.on_plperlu_init` (`string`) 这些参数指定当Perl解释器专门分别为`plperl`或`plperlu`时执行Perl代码。 当PL/Perl或PL/PerlU函数在一个数据库会话中第一次执行时会发生这种情况, 或当一个额外的解释器因为其他语言的调用或一个PL/Perl函数被一个新的SQL角色调用而创建时, 也会发生这种情况。这遵循任何由`plperl.on_init`所做的初始化。 当执行Perl代码时无法使用SPI函数。在`plperl.on_plperl_init`里面的Perl代码在 "锁定"解释器后执行,并且因此只能执行信任的操作。 如果代码因错误而失败,那么它将退出解释器的初始化,并且传播错误到调用的查询,导致当前事务或子事务退出。 任何Perl已经做的动作不会回滚;但是,那个解释器将不会再使用。如果语言再次被使用, 那么初始化将在一个新的Perl解释器中尝试。 只有超级用户可以改变这些设置。尽管这些设置可以在一个会话中改变, 但是这些改变将不会影响到已经用来执行函数的Perl解释器。 `plperl.use_strict` (`boolean`) 当设置PL/Perl函数的真实的后续编译时,将启用`strict`编译指示。 这个参数不影响已经用当前会话编译过的函数。 ## 42.7.2\. 限制及缺少的特性 下面的特性目前还在 PL/Perl 里面缺少,但是欢迎贡献。 * PL/Perl 函数无法相互直接调用。 * SPI 目前尚未完全实现。 * 如果你用`spi_exec_query`抓取非常大的数据集,你应该明白这些数据都会放到内存里。 你可以用前面演示的`spi_query`/`spi_fetchrow`来避免这些。 类似的问题也会发生在一个返回集合的函数用`return` 给 PostgreSQL 传递回去一个巨大的行集合。你也可以像前面演示的那样用`return_next` 返回每个返回行的方法避免这个问题。 * 当一个会话正常结束时,不是因为一个致命的错误而结束,执行任何已经定义的`END`块。 当前没有其他动作执行。特别的,文件句柄不自动刷新并且对象不自动销毁。