PostgreSQL函数中sql语言和plpgsql语言的区别

2024-05-20

我很新数据库开发所以我对下面的例子有一些疑问:

函数 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(使用前将#替换为@)

PostgreSQL函数中sql语言和plpgsql语言的区别 的相关文章

随机推荐