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 sql
或language plpgsql
。
任何有用的链接或function的答案将不胜感激。
SQL函数
是更好的select:
-
对于简单的标量查询 。 没有太多的计划,更好地节省任何开销。
-
每个会话单个呼叫 。 没有什么可以从PL / pgSQL所提供的计划caching和准备好的语句中获得。 见下文。
-
如果它们通常在更大的查询语境中被调用,并且足够简单,就可以被内联 。
-
缺乏像PL / pgSQL这样的过程语言的经验 。 许多人都很熟悉SQL,这就是所有你需要的SQL函数。 关于PL / pgSQL几乎没有什么可说的。
-
有点短的代码。 没有块开销。
PL / pgSQL函数
是更好的select:
-
当你需要任何在SQL函数中不可用的过程元素或variables时 ,显然。
-
对于任何types的dynamicSQL , dynamic构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,正如你发现的那样,例如,你不能在没有INTO
或RETURN QUERY
情况下使用SELECT
。 PL / PgSQL也可以在DO
块中用于一次性程序。
sql
函数只能使用纯SQL,但通常效率更高,写起来更简单,因为您不需要BEGIN ... END;
块等.SQL函数可以内联,这对于PL / PgSQL来说是不正确的。
人们经常使用PL / PgSQL,因为它们习惯于程序思考。 在大多数情况下,当你认为你需要PL / PgSQL时,你可能不需要。 recursionCTE,横向查询等通常满足大多数需求。
欲了解更多信息…请参阅手册。