一尘不染

将复合类型的数组传递给存储过程

sql

我在形成文字时可能做错了。假设我有一个简单的存储过程,如下所示:

CREATE OR REPLACE FUNCTION do_something(input_array composite_type[])
  RETURNS SETOF text AS
$BODY$
DECLARE
    temp_var composite_type;
BEGIN

    FOR temp_var IN SELECT unnest(input_array) LOOP
        return next temp_var.message;
    END LOOP;

END
$BODY$
  LANGUAGE plpgsql;

composite_type定义为:

CREATE TYPE composite_type AS
   (message text,
    amount numeric(16,2));

执行这样的查询:

SELECT * FROM do_something('{"(test,11)","(test2,22)"}')

产生以下结果集:

(test,11.00)
(test2,22.00)

代替:

test
test2

我的文字是否有问题,还是应该message以其他方式访问该字段?感谢您的任何建议。


阅读 126

收藏
2021-03-10

共1个答案

一尘不染

指定输入的方式看起来不错,因为使用行和数组构造器语法可以观察到相同的行为:

SELECT * FROM do_something( ARRAY[ ROW('test',11), ROW('test2',22) ]::composite_type[] );

和:

SELECT ARRAY[ ROW('test',11), ROW('test2',22) ]::composite_type[];

产生:

 '{"(test,11.00)","(test2,22.00)"}'

如果添加:

 RAISE NOTICE '!%!',temp_var;

在循环内部,输出为:

NOTICE:  !("(test,11.00)",)!
NOTICE:  !("(test2,22.00)",)!

表明您实际上正在获取一个元组,其中“ message”是您期望的元组文本,并且为空“ amount”。

所以。为什么?

这有点微妙。您正在使用:

SELECT unnest(input_array)

这似乎可以满足您的要求,对:

regress=>     SELECT unnest( ARRAY[ ROW('test',11), ROW('test2',22) ]::composite_type[] );
    unnest     
---------------
 (test,11.00)
 (test2,22.00)
(2 rows)

…但是实际上,它返回的是type的 单个列composite_type。PL / PgSQL复合类型分配期望 每个类型列有一个列
。因此,单个列被推到“消息”中,没有第二个列。

相反,写:

SELECT * FROM unnest(input_array)

解压复合材料以进行分配。然后它按预期工作:

regress=> SELECT * FROM do_something( ARRAY[ ROW('test',11), ROW('test2',22) ]::composite_type[] );
 do_something 
--------------
 test
 test2
(2 rows)

如果的第一个字段composite_type为非文本类型,则您将得到一个错误信息,该错误信息会提供更多信息。

2021-03-10