您自己将手册中的关键句子加粗了:
SQL函数的整个主体在执行任何函数之前都会被解析。
另请参阅手册中有关
解析器阶段 的信息。
它由两个主要部分组成: 解析器 和 转换过程
。引用手册:
在 改造过程中 需要由解析器树递回作为输入,并确实了解哪些表,函数,和运营商查询所引用所需的语义解释。
如果SQL函数包含以下命令:
CREATE TABLE foo (...);INSERT INTO foo VALUES(...);
几乎同时计划了这两个语句(基于系统目录的相同快照)。因此,
INSERT不能看到表“ foo”可能是由上一条
CREATE命令创建的。这就产生
了以下问题之一 :
- 如果没有 其他的 名为“foo”表在你
search_patch
(还),Postgres的抱怨 试图创建时 的功能:
ERROR: relation "foo" does not exist
- 如果您的表中已经存在另一个名为“ foo”的表
search_patch
(并且您不使用冲突的列名),则Postgres将INSERT
基于该表进行计划。如果任何值导致(错误!)表中的冲突,通常会 在执行时 导致错误。或者,如果运气不好,它甚至可能在没有错误消息的情况下写入该表!非常偷偷摸摸的错误。
使用 PL / pgSQL 函数不会发生这种情况,因为它会将SQL命令像预处理语句一样按 _ 顺序_
计划和执行。因此,每个语句都可以查看在先前语句中创建的对象。
因此,从未访问过的语句甚至都不会被计划-与SQL函数不同。语句的执行计划可以缓存在同一会话中-与SQL函数不同。在此处阅读有关PL /
pgSQL函数中计划缓存的详细信息。



