使用多个复合输出参数调用 PostgreSQL 函数

Posted

技术标签:

【中文标题】使用多个复合输出参数调用 PostgreSQL 函数【英文标题】:Call PostgreSQL function with multiple composite output parameters 【发布时间】:2012-04-05 08:10:26 【问题描述】:

我想在 PostgreSQL 9.1 中定义一个函数,它接受多个复合类型的 INOUT 参数,但我不知道如何调用它。

例如。

CREATE TYPE my_type_a AS (a integer, b float);
CREATE TYPE my_type_b AS (c boolean, d varchar(5));

CREATE FUNCTION my_complex_func(INOUT a my_type_a, INOUT b my_type_b)
RETURNS RECORD
'...'
LANGUAGE plpgsql;

定义语句执行得很好,但我不知道如何调用这个函数!我试过了:

SELECT INTO a, b
    a, b FROM my_complex_func(a, b);

但这会报错:

ERROR:  record or row variable cannot be part of multiple-item INTO list

【问题讨论】:

【参考方案1】:

我认为这与您的输入类型或输入数量无关。

不返回 RECORD,返回真正的复合类型(使用 CREATE TYPE 定义)。

错误 record or row variable cannot be part of multiple-item INTO list 是因为您试图将一个 ROW 嵌套在另一个 ROW 中。

这应该可行:

CREATE TYPE my_type_a AS (a integer, b float);
CREATE TYPE my_type_b AS (c boolean, d varchar(5));
CREATE TYPE ret_type  AS (w integer, v boolean);

CREATE FUNCTION my_complex_func(INOUT a my_type_a, INOUT b my_type_b)
RETURNS ret_type as $$
 ...
$$ LANGUAGE plpgsql;

然后你可以这样做:

SELECT INTO a, b 
  (x.comp).w, (x.comp).v 
  FROM (select my_complex_func(j, i) as comp) x;

这个具体的例子对我有用:

create type smelly1 as (a integer, b text);
create type smelly2 as (a boolean, b float);
create type rettype as (w integer, v boolean);
create function foo_func(n smelly1, m smelly2) returns rettype as $$
declare
  f_ret rettype;
begin
   f_ret.w := n.a;
   f_ret.v := m.a;
   return f_ret;
end;
$$ language plpgsql;

select (x.comp).w, (x.comp).v from 
  (select foo_func('(4, hello)'::smelly1, '(true,3.14)'::smelly2) as comp) x;

返回:

 w | v 
---+---
 4 | t
(1 row)

【讨论】:

糟糕,忘记从子查询 (x) 中写入字段名 (comp) 是的,但是我需要返回一个复杂类型的两个实例(在这种情况下是相同的类型,但可能不同)。当有OUT参数时我必须返回记录:ERROR: function result type must be record because of OUT parameters。当然,如果有一些方法可以在没有 OUT 参数的情况下执行此操作,也可以。 你用 OUT 参数做什么? 无论您使用 OUT 参数做什么,您都应该能够以更加复合的类型返回 :-) 是的,我可以定义另一个复合类型来保存返回值,由现有的复合类型组成——但是对于原则上如此简单的事情来说,这有点难看。所以在这种情况下,我最终将我的函数分成两个(所以每个返回一个复合值)。无论如何感谢您的帮助,请 +1。

以上是关于使用多个复合输出参数调用 PostgreSQL 函数的主要内容,如果未能解决你的问题,请参考以下文章

复合数组类型作为 PostgreSQL 中的 OUTPUT 参数

当多个函数使用它时如何更改复合类型?

PostgreSQL Oracle 兼容性之存储过程

如何使用 jOOQ 更新 PostgreSQL 上复合列的单个子字段?

Postgresql:复合类型并选择进入

ThinkPHP模板之变量输出、自定义函数与判断语句用法