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

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

函数 f1()-< strong > language sql

 create or replace function f1(istr  varchar)
returns text as $$
select 'hello! '::varchar || istr;
$$ language sql;

函数 f2()-< strong > language 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'):

    ERROR: query 没有结果数据的目的地 提示: 如果要放弃 SELECT 的结果,请改为使用 PERFORM。 CONTEXT: PL/pgSQL 函数 f11(字符变化) SQL 语句第2行 错误

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

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

52533 次浏览

PL/PgSQL is a PostgreSQL-specific procedural language based on SQL. It has loops, variables, error/exception handling, etc. Not all SQL is valid PL/PgSQL - as you discovered, for example, you can't use SELECT without INTO or RETURN QUERY. PL/PgSQL may also be used in DO blocks for one-shot procedures.

sql functions can only use pure SQL, but they're often more efficient and they're simpler to write because you don't need a BEGIN ... END; block, etc. SQL functions may be inlined, which is not true for PL/PgSQL.

People often use PL/PgSQL where plain SQL would be sufficient, because they're used to thinking procedurally. In most cases when you think you need PL/PgSQL you probably actually don't. Recursive CTEs, lateral queries, etc generally meet most needs.

For more info ... see the manual.

SQL functions

... are the better choice:

  • For simple scalar queries. Not much to plan, better save any overhead.

  • For single (or very few) calls per session. Nothing to gain from plan caching via prepared statements that PL/pgSQL has to offer. See below.

  • If they are typically called in the context of bigger queries and are simple enough to be inlined.

  • For lack of experience with any procedural language like PL/pgSQL. Many know SQL well and that's about all you need for SQL functions. Few can say the same about PL/pgSQL. (Though it's rather simple.)

  • A bit shorter code. No block overhead.

PL/pgSQL functions

... are the better choice:

  • When you need any procedural elements or variables that are not available in SQL functions, obviously.

  • For any kind of dynamic SQL, where you build and EXECUTE statements dynamically. Special care is needed to avoid SQL injection. More details:

  • When you have computations that can be reused in several places and a CTE can't be stretched for the purpose. In an SQL function you don't have variables and would be forced to compute repeatedly or write to a table. This related answer on dba.SE has side-by-side code examples for solving the same problem using an SQL function / a plpgsql function / a query with CTEs:

Assignments are somewhat more expensive than in other procedural languages. Adapt a programming style that doesn't use more assignments than necessary.

Also consider:


To actually return from a PL/pgSQL function, you could write:

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

There are other ways:

just make the select query you wrote inside the function as the returned value:

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