首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >语言sql与语言plpgsql在PostgreSQL函数中的区别

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

Stack Overflow用户
提问于 2014-07-15 10:10:41
回答 3查看 52.4K关注 0票数 88

我在数据库开发方面非常新,所以我对下面的示例有一些疑问:

函数f1() -语言sql

代码语言:javascript
复制
 create or replace function f1(istr  varchar)
 returns text as $$ 
 select 'hello! '::varchar || istr;
 $$ language sql;

函数f2() -语言plpgsql

代码语言:javascript
复制
 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')的输出: 错误:查询没有结果数据提示的目标:如果要放弃选择的结果,请使用“执行”。上下文: PL/pgSQL函数f11(字符变化),在SQL语句*错误*处第2行
  • 我希望知道不同之处,以及在何种情况下我应该使用language sql或language plpgsql。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-16 03:06:03

SQL函数

..。更好的选择是:

  • 对于简单标量查询,。没有什么可计划的,最好节省任何开销。
  • 对于,每个会话只有一个(或极少数)调用,。通过PL/pgSQL必须提供的预准备语句进行计划缓存没有任何好处。见下文。
  • 如果它们通常在大型查询的上下文中被调用,并且非常简单,足以成为内嵌。
  • 由于缺乏经验,所以使用PL/pgSQL之类的过程语言的。很多人都很了解SQL,这就是SQL函数所需要的全部内容。对于PL/pgSQL,很少有人能这样说。(虽然很简单。)
  • 稍微短一点的代码。在头顶上没有街区。

PL/pgSQL函数

..。更好的选择是:

  • 显然,当您需要任何过程元素或变量时,这些元素在SQL函数中是不可用的。
  • 对于任何类型的动态SQL,都可以动态地构建和EXECUTE语句。需要特别注意避免SQL注入。更多详细信息:
代码语言:javascript
复制
- [Postgres functions vs prepared queries](https://dba.stackexchange.com/a/49718/3684)
  • 当您有可以被computations重用的时,可以在几个地方重用,并且不能为此目的扩展一个CTE。在SQL函数中,您没有变量,将被迫重复计算或写入表。dba.SE上的这一相关答案具有并行代码示例,用于使用SQL函数/ plpgsql函数/CTEs查询解决相同问题:
代码语言:javascript
复制
- [How to pass a parameter into a function](https://dba.stackexchange.com/a/71442/3684)

作业比其他程序语言要贵一些。采用一种不需要过多作业的编程风格。

  • 当一个函数不能内联并被反复调用时。与SQL函数不同的是,对于PL/pgSQL函数中的所有SQL语句;它们被视为准备语句,该计划被缓存用于同一会话内的重复调用(如果Postgres希望缓存(泛型)计划比每次重新规划更好的话)。这就是为什么PL/pgSQL函数是的原因,在这种情况下,在最初的几次调用之后,通常会更快。 下面是关于pgsql性能的一个线程,讨论这些项目中的一些:
代码语言:javascript
复制
- [Re: pl/pgsql functions outperforming sql ones?](https://www.postgresql.org/message-id/flat/0238E40E527049828C48675488422F6D@CAPRICA#0238E40E527049828C48675488422F6D@CAPRICA)
  • 当你需要陷阱误差的时候。
  • 为了触发函数。
  • 当包括DDL语句、更改对象或更改与后续命令相关的系统目录时--因为SQL函数中的所有语句同时被解析,而PL/pgSQL函数则按顺序计划和执行每个语句(就像准备好的语句)。请参见:
代码语言:javascript
复制
- [Why can PL/pgSQL functions have side effect, while SQL functions can't?](https://stackoverflow.com/questions/51004980/why-can-pl-pgsql-functions-have-side-effect-while-sql-functions-cant/51033884#51033884)

还应考虑:

要真正从PL/pgSQL函数返回,可以编写:

代码语言:javascript
复制
CREATE FUNCTION f2(istr varchar)
  RETURNS text AS
$func$
BEGIN
   RETURN 'hello! ';  -- defaults to type text anyway
END
$func$ LANGUAGE plpgsql;

还有其他方式:

票数 122
EN

Stack Overflow用户

发布于 2014-07-15 10:31:13

PL/PgSQL是一种基于SQL的PostgreSQL专用过程语言。。它有循环、变量、错误/异常处理等。不是所有的SQL都是有效的PL/PgSQL --例如,您发现没有INTO或RETURN QUERY就不能使用RETURN QUERY。PL/PgSQL也可以用于DO块中的一次性过程.

函数只能使用纯SQL,但是它们通常更高效,而且编写起来更简单,因为您不需要BEGIN ... END;块等等。SQL函数可能是内联的,PL/PgSQL不是这样的。

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

想了解更多信息..。看手册。

票数 22
EN

Stack Overflow用户

发布于 2018-11-14 14:36:27

只需将在函数中编写的select查询作为返回的值:

代码语言:javascript
复制
 create  or replace function f2(istr  varchar)
 returns text as $$ 
 begin return(select 'hello! '::varchar || istr); end;
 $$ language plpgsql;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24755468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档