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

时间:2014-07-15 10:10:42

标签: sql function postgresql stored-procedures 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。          语境:SQL语句中的PL / pgSQL函数f11(字符变化)第2行           ****** 错误 ******

  • 我希望了解差异,以及在哪种情况下我应该使用language sqllanguage plpgsql

非常感谢有关功能的任何有用链接或答案。

3 个答案:

答案 0 :(得分:44)

SQL functions

是更好的选择:

  • 对于简单标量查询。计划不多,更好地节省开支。

  • 对于每个会话的单个(或极少数)呼叫。通过PL / pgSQL提供的预准备语句从计划缓存中无法获得任何好处。见下文。

  • 如果通常在更大的查询环境中调用它们,并且它们非常简单,可以inlined

  • 缺少体验与任何程序语言,如PL / pgSQL。许多人都熟悉SQL,并且了解SQL函数所需的全部内容。很少有人能说PL / pgSQL。 (虽然它很简单。)

  • 更短的代码。没有阻止开销。

PL/pgSQL functions

是更好的选择:

  • 当您需要SQL功能中不可用的任何程序元素变量时,显然。

  • 对于任何类型的动态SQL ,您可以动态地构建和EXECUTE语句。需要特别小心以避免SQL注入。更多细节:

  • 如果计算可以在多个地方重复使用,则无法为此目的拉伸CTE。在SQL函数中,您没有变量,将被迫重复计算或写入表。这个关于dba.SE的相关答案有并排的代码示例,用于使用SQL函数/ plpgsql函数/ CTE查询来解决相同的问题:

    作业比其他程序语言贵一些。适应不使用必要的更多作业的编程风格。

  • 当函数无法内联并重复调用时。与SQL函数不同,query plans can be cached for all SQL statements inside a PL/pgSQL functions;它们被视为预备语句,计划被缓存以便在同一会话中重复调用(如果Postgres希望缓存(通用)计划的性能优于每次重新计划。)在这种情况下,在前几次调用之后PL / pgSQL函数 通常更快 的原因。

    这是一个关于pgsql-performance的讨论其中一些项目的线程:
    Re: pl/pgsql functions outperforming sql ones?

  • 当您需要trap errors.

  • 对于trigger procedures(它们也只是功能)。

  • 当包含DDL语句以与后续命令相关的任何方式更改对象或更改系统目录时 - 因为PL / pgSQL函数计划并按顺序执行每个语句时,SQL函数中的所有语句都会被立即解析(如准备好的语句) )。参见:

还要考虑:


要从PL / pgSQL函数实际返回,您可以写:

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

还有其他方法:

答案 1 :(得分:14)

PL/PgSQL is a PostgreSQL-specific procedural language based on SQL。它有循环,变量,错误/异常处理等。并非所有SQL都是有效的PL / PgSQL - 例如,您发现,如果没有SELECT或{{{{}}},则不能使用INTO 1}}。 PL / PgSQL也可以在RETURN QUERY块中用于一次性程序。

sql functions只能使用纯SQL,但它们通常效率更高,而且编写起来更简单,因为您不需要DO块等。 SQL函数可能是内联的,而PL / PgSQL则不然。

人们经常使用PL / PgSQL,其中普通的SQL就足够了,因为他们习惯于在程序上进行思考。在大多数情况下,当你认为你需要PL / PgSQL时,你可能实际上并不是这样。递归CTE,横向查询等通常满足大多数需求。

有关详细信息,请参阅手册。

答案 2 :(得分:0)

只需使您在函数内部编写的选择查询作为返回值即可:

 create  or replace function f2(istr  varchar)
 returns text as $$ 
 begin return(select 'hello! '::varchar || istr); end;
 $$ language plpgsql;