当前位置: 首页 > 知识库问答 >
问题:

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

郎吉星
2023-03-14

我对数据库开发非常陌生,因此我对以下示例有一些疑问:

函数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;

>

  • 这两个函数都可以像选择f1('world')选择f2('world')一样调用。

    如果我调用选择f1('world'),输出将是:

     `hello! world`
    

    并为选择f2(“世界”)输出:

    错误:查询没有结果数据的目的地提示:如果要丢弃SELECT的结果,请改为使用PERFORM。上下文:PL/pgSQL函数f11(字符变化)第2行SQL语句 ********** 错误 **********

    我想知道两者的区别,以及在哪些情况下我应该使用语言sql语言plpgsql

    任何关于函数的有用链接或答案都将不胜感激。

  • 共有3个答案

    谷梁嘉运
    2023-03-14

    只需将选择查询作为返回值写入函数中:

     create  or replace function f2(istr  varchar)
     returns text as $$ 
     begin return(select 'hello! '::varchar || istr); end;
     $$ language plpgsql;
    
    杜成和
    2023-03-14

    PL/PgSQL是一种基于SQL的特定于PostgreSQL的过程语言。它有循环、变量、错误/异常处理等。并非所有SQL都是有效的PL/PgSQL——例如,正如您所发现的,您不能使用SELECT,而不使用进入返回查询。PL/PgSQL也可用于单发程序的DO块中。

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

    人们经常使用PL/PgSQL,在那里简单的SQL就足够了,因为他们习惯于程序化思考。在大多数情况下,当你认为你需要PL/PgSQL时,你可能实际上不需要。递归CTE、横向查询等通常满足大多数需求。

    有关更多信息,请参阅手册。

    西门高歌
    2023-03-14

    ... 是更好的选择:

    >

  • 用于简单的标量查询。计划不多,最好节省开销。

    对于每个会话的单个(或很少)呼叫。通过PL/pgSQL必须提供的准备好的语句,计划缓存不会带来任何好处。见下文。

    如果它们通常在较大查询的上下文中调用,并且足够简单,可以内联。

    缺乏任何过程语言的经验,如PL/pgSQL。许多人非常了解SQL,这就是SQL功能所需的全部。很少有人能对PL/pgSQL说同样的话。(虽然这很简单。)

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

    ... 是更好的选择:

    >

  • 当您需要SQL函数中不可用的任何过程元素或变量时。

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

    • Postgres函数vs准备查询

    当你有可以在几个地方重用的计算,并且CTE不能为此目的扩展时。在SQL函数中,您没有变量,将被迫重复计算或写入表。关于dba的相关回答。SE有并行代码示例,用于使用SQL函数/plpgsql函数/CTE查询来解决相同的问题:

    • 如何将参数传递给函数

    赋值比其他过程语言的赋值要贵一些。调整一种编程风格,不要使用过多的任务。

    >

  • 当函数不能内联并被重复调用时。与SQL函数不同,可以缓存PL/pgSQL函数中所有SQL语句的查询计划;它们被视为准备好的语句,该计划被缓存为同一会话中的重复调用(如果Postgres期望缓存(泛指)每次都计划比重新计划表现更好。这就是为什么在这种情况下,PL/pgSQL函数通常在头几次调用后速度更快的原因。

    下面是一篇关于pgsql性能的文章,讨论了以下几点:

    • Re: pl/pgsql函数优于sql函数?

    当您需要捕获错误时。

    用于触发功能。

    当包含DDL语句时,以任何与后续命令相关的方式更改对象或更改系统目录——因为SQL函数中的所有语句都会一次解析,而PL/pgSQL函数会按顺序规划和执行每条语句(如准备好的语句)。见:

    • 为什么PL/pgSQL函数会有副作用,而SQL函数不会

    还应考虑:

    • 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函数在不使用变量的情况下返回整数吗
    • 关于“从功能返回”的手册

  •  类似资料:
    • 问题内容: 数据库开发 是一个非常新的事物,因此我对以下示例有一些疑问: 函数f1()- 语言sql 函数f2()- 语言plpgsql 这两个 函数 都可以称为或。 如果我打电话, 输出 将是: 并 输出 为: 错误:查询没有结果数据的目的地提示:如果要舍弃SELECT的结果,请改用PERFORM。上下文:SQL语句 *上的 PL / pgSQL函数f11(字符变化)第2行 * 错误 ** 我想

    • 我是PostgreSQL的新手,我面临着一个关于表函数性能的问题。我需要做的是相当于MSSQL中的存储过程。经过一些研究,我发现一个表函数是可行的,所以我举了一个例子,用plpgsql创建了我的函数。 通过比较执行时间,使用函数比直接调用查询慢2倍(查询在函数中完全相同)。 经过一点挖掘,我发现在函数中使用SQL语言可以大大提高执行时间(与调用查询的时间完全相同)。读了这篇文章后,我了解到plpg

    • 在 Go 语言开篇中我们已经知道,Go 语言与 C 语言之间有着千丝万缕的关系,甚至被称之为 21 世纪的C语言。 所以在 Go 与 C 语言互操作方面,Go 更是提供了强大的支持。尤其是在 Go 中使用 C,你甚至可以直接在 Go 源文件中编写 C 代码,这是其他语言所无法望其项背的。 格式: 在 import "C" 之前通过单行注释或者通过多行注释编写C语言代码 在 import "C" 之

    • 本文向大家介绍详解C语言中getgid()函数和getegid()函数的区别,包括了详解C语言中getgid()函数和getegid()函数的区别的使用技巧和注意事项,需要的朋友参考一下 C语言getgid()函数:取得组识别码函数 头文件: 定义函数: 函数说明:getgid()用来取得执行目前进程的组识别码。 返回值:返回组识别码 范例 执行: C语言getegid()函数:获得组识别码 头文

    • 主要内容:编译型语言,解释型语言,总结通过高级语言编写的源码,我们能够轻松理解,但对于计算机来说,它只认识二进制指令,源码就是天书,根本无法识别。源码要想执行,必须先转换成二进制指令。 所谓二进制指令,也就是由 0 和 1 组成的机器码,能被计算机直接识别并执行。 然而,究竟在什么时候将源代码转换成二进制指令呢?不同的编程语言有不同的规定: 有的编程语言要求必须提前将所有源代码一次性转换成二进制指令,也就是生成一个可执行程序(比如 W

    • 本文向大家介绍高级语言和低级语言之间的区别,包括了高级语言和低级语言之间的区别的使用技巧和注意事项,需要的朋友参考一下 让我们首先了解高级和低级语言- 高级语言 与低级语言相比,它易于解释和编译。 它可以被认为是程序员友好的语言。 很容易理解。 这很容易调试。 在维护方面很简单。 它要求将编译器/解释器翻译成机器代码。 它可以在不同的平台上运行。 它可以从一个位置移植到另一位置。 i.e与低级语言