暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PG中函数分类和区别

Thornger 2021-04-12
1702

PG提供了四种类型的函数

  • SQL语言函数(用SQL编写的函数)

  • 过程语言函数(用PL/PGSQL、PL/TCL等过程语言编写的)

  • 内部函数

  • C语言函数


    每种函数的参数都可以接受基类型、复合类型或这些类型的组合。此外,每种函数的返回值也可以返回基类型或复合类型或这些类型的集合。

  有些类型的函数可以接受或返回特定的伪类型(例如多态类型),有关详细信息,请参阅每种功能的描述。


  • SQL语言函数

    SQL语言函数返回列表中最后一个查询的结果。在简单的(非返回集合)情况下,将返回最后一个查询结果的第一行。(请记住,除非使用ORDER BY,否则多行结果的“第一行”是没有明确定义的。)如果最后一个查询恰好没有返回任何行,那么将返回null值。或者,可以声明一个SQL函数来返回一个集合(即多行),方法是将函数的返回类型指定为 SETOF+类型,或者等效地将它声明为RETURNS TABLE(columns)。在这种情况下,返回最后一个查询结果的所有行。

    create function test() returns int
    as $$
    select 1;
    select 2;
    select 3;
    $$
    language sql;


    postgres=# select test();
    test
    ------
    3
    (1 row)

       除非函数被声明为返回void,否则最后一条语句必须是一个SELECT或一个带有返回子句的INSERT、UPDATE或DELETE。

      create function test() returns int
      as $$
      select 1;
      select 2;
      insert into itable values(1);
      $$
      language sql;
      ERROR: return type mismatch in function declared to return integer
      DETAIL: Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING.
      CONTEXT: SQL function "test"
      STATEMENT: create function test() returns int
      as $$
      select 1;
      select 2;
      insert into itable values(1);
      $$
      language sql;
      ERROR: return type mismatch in function declared to return integer
      DETAIL: Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING.
      CONTEXT:  SQL function "test"

        SQL语言中的任何命令集合都可以打包在一起并定义为函数。除了选择查询外,这些命令还可以包括数据修改查询(插入、更新和删除),以及其他SQL命令。(您不能在SQL函数中使用事务控制命令,例如COMMIT、SAVEPOINT和一些实用命令,例如VACUUM。)但是,最后的命令必须是SELECT或具有return的子句,该子句返回指定为函数返回类型的任何内容。另外,如果希望定义一个执行操作但没有返回有用值的SQL函数,可以将其定义为返回void。


      • 过程语言函数

        过程语言并没有内置到PostgreSQL服务器中,它们由可加载模块提供。

        PostgreSQL允许用SQL和c之外的其他语言编写用户定义的函数。这些语言通常称为过程语言(PLS)。对于用过程语言编写的函数,数据库服务器没有关于如何解释函数源文本的内置知识。相反,任务被传递给一个知道语言细节的特殊处理程序。处理程序可以自己完成所有的解析、语法分析、执行等工作,处理程序本身是一个编译成共享对象并按需加载的C语言函数,就像任何其他C函数一样。


      • 内部函数

        内部函数是用C编写的函数,这些函数被静态地链接到PostgreSQL服务器。当用CREATE FUCTION 定义新函数时,函数的函数体需要指定该函数所用的内部函数的名称


        CREATE FUNCTION square_root(double precision) RETURNS double precision
        AS 'dsqrt'
        LANGUAGE internal
        STRICT;

        该C语言名称不必与SQL使用时声明的名称相同。(出于向后兼容性的原因,空体被接受为表示c语言函数名与SQL名称相同。)

        通常,服务器中出现的所有内部函数都是在数据库集群初始化期间声明的,但是用户可以使用CREATE函数为内部函数创建别名。内部函数在CREATE FUNCTION的函数的AS后中声明,语言名为Internal。


        • C语言函数

          用户定义的函数可以用C(或者一种与C兼容的语言,如c++)编写。这些函数被编译成可动态加载的对象(也称为共享库),并由服务器按需加载。

          动态加载特性是区分“C语言”函数和“内部”函数的关键——两者的实际编码约定本质上是相同的。(因此,标准内部函数库为用户定义的C函数提供了丰富的代码示例。)

          CREATE FUNCTION get_command_type(pg_ddl_command)
          RETURNS text IMMUTABLE STRICT
          AS 'MODULE_PATHNAME'
            LANGUAGE C;

          注意:

              当<object file name> [, <link symbol name> ] 没有指定[link symbol name]时,默认对应的C函数名与函数的函数名相同。

          文章转载自Thornger,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论