ARX*_*ARX 18 postgresql functions postgresql-14
在 PG 14 的文档中,在 参考资料CREATE FUNCTION
部分中,手册指出函数的主体LANGUAGE SQL
可以是单个语句:
RETURN expression
Run Code Online (Sandbox Code Playgroud)
或一个块:
BEGIN ATOMIC
statement;
statement;
...
statement;
END
Run Code Online (Sandbox Code Playgroud)
没有对该块的语义给出任何解释。这看起来类似于BEGIN ... END;
PL/pgSQL 中的块,但似乎有些不同。
在 内 或 外 写一组语句有什么区别BEGIN ATOMIC ... END
?什么时候需要使用这样的块?关键字是ATOMIC
强制的吗?
Erw*_*ter 21
它是SQL 标准函数的新语法变体(在 Postgres 14 中)。
发行说明:
允许 SQL 语言函数和过程使用 SQL 标准函数体 (Peter Eisentraut)
以前仅支持字符串文字函数体。当使用 SQL 标准语法编写函数或过程时,主体会立即被解析并存储为解析树。这可以更好地跟踪函数依赖关系,并且可以带来安全优势。
传统的 Postgres 函数和过程将正文保存为要在执行时解析的文字字符串,通常使用美元引用。看:
新语法BEGIN ATOMIC ... END
(强制ATOMIC
!)不引用函数体,该函数体在创建时进行解析。它只是看起来类似于 PL/pgSQL 块,用BEGIN ... END
. 两者非常不同。新的语法变体仅允许用于LANGUAGE sql
. 事实上,该语言是在没有声明的情况下假定的。手册:
sql
如果指定则默认为sql_body
。
您可以编写多个纯 SQL 语句,就像传统的字符串文字函数或过程体一样。但所有内容都是在函数创建时解析的。因此,传统字符串文字形式的“早期绑定”与“后期绑定”。这有许多副作用。手册中
对 SQL 标准语法有很好的解释:
这类似于将函数体的文本写为字符串常量(参见上面的定义),但有一些区别: 这种形式仅适用于
LANGUAGE SQL
,字符串常量形式适用于所有语言。这种形式在函数定义时解析,字符串常量形式在执行时解析;因此,这种形式不能支持多态参数类型和其他在函数定义时无法解析的构造。这种形式跟踪函数和函数体中使用的对象之间的依赖关系,因此DROP ... CASCADE
可以正常工作,而使用字符串文字的形式可能会留下悬空函数。最后,这种形式与SQL标准和其他SQL实现更加兼容。
“SQL 标准”形式也可以是“内联”的。看:
新的语法变体通常更适合简单的 SQL 函数。
带(且不带关键字)的单个表达式的缩写形式:RETURN
ATOMIC
CREATE OR REPLACE FUNCTION asterisk(n int)
RETURNS text
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
RETURN repeat('*', n);
Run Code Online (Sandbox Code Playgroud)
完整形式:
CREATE OR REPLACE FUNCTION asterisks(n int)
RETURNS SETOF text
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
BEGIN ATOMIC
SELECT repeat('*', g) FROM generate_series (1, n) g;
END;
Run Code Online (Sandbox Code Playgroud)
作为参考,与具有字符串文字主体的传统 SQL 函数相同:
CREATE OR REPLACE FUNCTION asterisks(n int)
RETURNS SETOF text
LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE AS
$func$
SELECT repeat('*', g) FROM generate_series (1, n) g;
$func$;
Run Code Online (Sandbox Code Playgroud)
或者作为 PL/pgSQL 函数:
CREATE OR REPLACE FUNCTION asterisks(n int)
RETURNS SETOF text
LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE AS
$func$
BEGIN
RETURN QUERY
SELECT repeat('*', g) FROM generate_series (1, n) g;
END
$func$;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8366 次 |
最近记录: |