Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

43.2. PL/Python 函数

PL/Python中的函数通过标准的CREATE FUNCTION语法声明:

CREATE FUNCTION funcname (argument-list)
  RETURNS return-type
AS $$
  # PL/Python function body
$$ LANGUAGE plpythonu;

函数体是一个简单的Python脚本,当函数被调用的时候,它的参数作为列表args 的元素传递;命名参数也会被当做普通的变量传递到Python脚本中。命名参数的使用通常更易读。 结果将使用returnyield(结果集语句的情况) 照常从Python代码中返回。如果没有提供返回值,Python返回缺省的NonePL/Python翻译Python的None为SQL空值。

比如,返回两个整数中较大者的函数可以定义为:

CREATE FUNCTION pymax (a integer, b integer)
  RETURNS integer
AS $$
  if a > b:
    return a
  return b
$$ LANGUAGE plpythonu;

以函数体定义形式给出的Python代码转换成Python函数。比如,上面的转换成:

def __plpython_procedure_pymax_23456():
  if a > b:
    return a
  return b

这里假设23456是PostgreSQL赋予这个函数的OID。

参数设置为全局变量。因为Python的作用域规则,这有些微妙的结果, 参数变量在函数内部不能分配给包含变量名本身的表达式值, 除非变量在块中重新定义为全局。例如,以下是行不通的:

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  x = x.strip()  # error
  return x
$$ LANGUAGE plpythonu;

因为分配到的x产生整个块的局部变量x, 所以x在分配的右侧指向一个未被分配的局部变量x, 不是PL/Python函数参数。使用global声明,这可以使其运行:

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  global x
  x = x.strip()  # ok now
  return x
$$ LANGUAGE plpythonu;

但最好不要依赖PL/Python的执行细节。最好是把函数参数作为只读的。