我很新数据库开发所以我对下面的例子有一些疑问:
函数 f1() -语言 SQL
create or replace function f1(istr varchar)
returns text as $$
select 'hello! '::varchar || istr;
$$ language sql;
函数 f2() -语言 plpgsql
create or replace function f2(istr varchar)
returns text as $$
begin select 'hello! '::varchar || istr; end;
$$ language plpgsql;
-
Both 功能可以这样称呼select f1('world')
or select f2('world')
.
-
如果我打电话select f1('world')
the output将:
`hello! world`
-
And output for select f2('world')
:
错误:查询没有结果数据的目标
提示:如果您想放弃 SELECT 的结果,请使用 PERFORM。
上下文:PL/pgSQL 函数 f11(字符变化)SQL 语句第 2 行
********** 错误 **********
-
我想知道其中的区别以及我应该在哪些情况下使用language sql
or language plpgsql
.
任何有关功能的有用链接或答案将不胜感激。
SQL函数 https://www.postgresql.org/docs/current/xfunc-sql.html
...是更好的选择:
-
For 简单的标量查询。不需要太多计划,最好节省一些开销。
-
For 每个会话单个(或很少)调用。通过 PL/pgSQL 提供的准备好的语句进行计划缓存没有任何好处。见下文。
-
如果它们通常在更大的查询上下文中调用并且足够简单inlined https://wiki.postgresql.org/wiki/Inlining_of_SQL_functions.
-
由于缺乏经验与任何过程语言(如 PL/pgSQL)。许多人都非常了解 SQL,这就是 SQL 函数所需的全部内容。很少有人能对 PL/pgSQL 做出同样的评价。 (虽然这很简单。)
-
代码短一点。没有块开销。
PL/pgSQL 函数 https://www.postgresql.org/docs/current/plpgsql.html
...是更好的选择:
-
当你需要任何程序要素 or 变量显然,这在 SQL 函数中是不可用的。
-
对于任何一种动态SQL,你建造的地方和EXECUTE https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN动态声明。需要特别小心以避免 SQL 注入。更多细节:
- Postgres 函数与准备好的查询 https://dba.stackexchange.com/a/49718/3684
-
当你有计算那可以是reused在几个地方,CTE 无法为此目的而延伸。在 SQL 函数中,您没有变量,并且将被迫重复计算或写入表。 dba.SE 上的这个相关答案并排代码示例使用 SQL 函数/plpgsql 函数/带有 CTE 的查询解决相同的问题:
- 如何将参数传递给函数 https://dba.stackexchange.com/a/71442/3684
与其他过程语言相比,赋值的成本要高一些。适应一种不使用不必要的作业的编程风格。
-
当函数无法内联并被重复调用时。与 SQL 函数不同,查询计划可以被缓存对于 PL/pgSQL 函数内的所有 SQL 语句 https://www.postgresql.org/docs/current/plpgsql-implementation.html#PLPGSQL-PLAN-CACHING;他们受到的待遇就像准备好的陈述,该计划被缓存以供同一会话中的重复调用(如果 Postgres 期望缓存的(通用)计划比每次重新计划执行得更好。这就是 PL/pgSQL 函数的原因通常更快在这种情况下,在前几次通话之后。
这是关于 pgsql-performance 的一个线程,讨论了其中一些项目:
- 回复: pl/pgsql 功能优于 sql 功能吗? https://www.postgresql.org/message-id/flat/0238E40E527049828C48675488422F6D@CAPRICA#0238E40E527049828C48675488422F6D@CAPRICA
-
当你需要时陷阱错误 https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING.
-
For 触发功能 https://www.postgresql.org/docs/current/plpgsql-trigger.html.
-
当包含以与后续命令相关的任何方式更改对象或更改系统目录的 DDL 语句时 - 因为 SQL 函数中的所有语句都会立即解析,而 PL/pgSQL 函数会按顺序计划和执行每个语句(如准备好的语句)。看:
- 为什么PL/pgSQL函数可以有副作用,而SQL函数却不能? https://stackoverflow.com/questions/51004980/why-can-pl-pgsql-functions-have-side-effect-while-sql-functions-cant/51033884#51033884
还要考虑:
- PostgreSQL 存储过程性能 https://dba.stackexchange.com/a/8189/3684
实际上return从 PL/pgSQL 函数,您可以编写:
CREATE FUNCTION f2(istr varchar)
RETURNS text AS
$func$
BEGIN
RETURN 'hello! '; -- defaults to type text anyway
END
$func$ LANGUAGE plpgsql;
还有其他方法:
- 我可以让 plpgsql 函数在不使用变量的情况下返回整数吗? https://stackoverflow.com/questions/8169676/can-i-make-a-plpgsql-function-return-an-integer-without-using-a-variable/8169928#8169928
- “从函数返回”手册 https://www.postgresql.org/docs/current/plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)