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

数据库开发中是非常新的,所以我对我的下面的例子有一些怀疑:

函数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; 
  • 这两个函数可以被称为select f1('world')select f2('world')

  • 如果我调用select f1('world')输出将是:

     `hello! world` 
  • 输出 select f2('world')

    错误:查询没有结果数据的目标提示:如果您想放弃SELECT的结果,请改用PERFORM。 CONTEXT:PL / pgSQL函数f11(字符变化)第2行SQL语句******错误******

  • 我想知道的区别,在哪些情况下,我应该使用language sqllanguage plpgsql

任何有用的链接或function的答案将不胜感激。

SQL函数

是更好的select:

  • 对于简单的标量查询 。 没有太多的计划,更好地节省任何开销。

  • 每个会话单个呼叫 。 没有什么可以从PL / pgSQL所提供的计划caching和准备好的语句中获得。 见下文。

  • 如果它们通常在更大的查询语境中被调用,并且足够简单,就可以被内联

  • 缺乏像PL / pgSQL这样的过程语言的经验 。 许多人都很熟悉SQL,这就是所有你需要的SQL函数。 关于PL / pgSQL几乎没有什么可说的。

  • 有点短的代码。 没有块开销。

PL / pgSQL函数

是更好的select:

  • 当你需要任何在SQL函数中不可用的过程元素variables时 ,显然。

  • 对于任何types的dynamicSQLdynamic构build和EXECUTE语句。 需要特别注意避免SQL注入。 更多细节:

    • Postgres函数与准备的查询
  • 当你有几个地方可以重复使用的 计算 ,CTE不能被拉伸的目的。 在SQL函数中,您没有variables,将被强制重复计算或写入表。 这个在dba.SE上的相关答案有解决使用SQL函数/ plpgsql函数/查询与CTE相同的问题的并行代码示例

    • 如何将一个parameter passing给一个函数

    分配比其他过程语言要贵一些。 改编一个不需要使用更多任务的编程风格。

  • 当函数不能被内联并被重复调用时。 与SQL函数不同的是, 可以为PL / pgSQL函数中的所有SQL语句caching查询计划 ; 他们被视为准备好的语句 ,计划被caching在同一个会话中重复调用(如果Postgres希望caching(通用)计划比每次重新计划更好地执行,这就是为什么PL / pgSQL函数通常会更快在这种情况下的第一个几个电话。

    这里是讨论一些这些项目的pgsql-性能的线程:
    回复:pl / pgsql的function优于sql的?

  • 当你需要捕捉错误

  • 对于触发程序 (这也只是function)。

还要考虑:

  • PostgreSQL存储过程的性能

为了完整:实际上从PL / pgSQL函数返回 ,你可以这样写:

 CREATE FUNCTION f2(istr varchar) RETURNS text AS $func$ BEGIN RETURN 'hello! '; -- defaults to type text anyway END $func$ LANGUAGE plpgsql; 

还有其他的方法:

  • 我可以让一个plpgsql函数返回一个整数,而不使用variables?
  • “从函数返回”手册

PL / PgSQL是基于SQL的特定于PostgreSQL的过程语言 。 它有循环,variables,错误/exception处理等等。并不是所有的SQL都是有效的PL / PgSQL,正如你发现的那样,例如,你不能在没有INTORETURN QUERY情况下使用SELECT 。 PL / PgSQL也可以在DO块中用于一次性程序。

sql函数只能使用纯SQL,但通常效率更高,写起来更简单,因为您不需要BEGIN ... END; 块等.SQL函数可以内联,这对于PL / PgSQL来说是不正确的。

人们经常使用PL / PgSQL,因为它们习惯于程序思考。 在大多数情况下,当你认为你需要PL / PgSQL时,你可能不需要。 recursionCTE,横向查询等通常满足大多数需求。

欲了解更多信息…请参阅手册。