簡體   English   中英

將復合類型的數組傳遞給存儲過程

[英]Passing array of a composite type to stored procedure

我可能在形成文字方面做錯了。 假設我有一個這樣的簡單存儲過程:

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字段? 謝謝你的任何建議。

如何指定輸入似乎很好,因為使用行和數組構造函數語法觀察到相同的行為:

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”作為你期望的元組文本和null“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)

...但實際上,它返回的是一個類型為composite_type PL / PgSQL復合類型賦值需要每個類型列一列 所以單個col被推入'消息'並且沒有第二個col。

相反,寫:

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的第一個字段是非文本類型,那么您將收到一個錯誤信息,該信息對此有更多信息。

Craig很好地解釋了這種行為的原因 - 在FOR語句中賦值變量=值期望零嵌套。 所以你應該這樣做:

CREATE OR REPLACE FUNCTION do_something(input_array composite_type[])
RETURNS SETOF text AS $BODY$
DECLARE
    temp_var record;
BEGIN
     -- unnesting
    FOR temp_var IN SELECT (unnest(input_array)).*
    LOOP
        RETURN NEXT temp_var.message;
    END LOOP;
    RETURN;
END
$BODY$ LANGUAGE plpgsql;

或者 - 更好 - 更新在“列列表”中使用SetReturnedFunction

CREATE OR REPLACE FUNCTION do_something(input_array composite_type[])
RETURNS SETOF text AS $BODY$
DECLARE
    temp_var record;
BEGIN
     -- SELECT FROM
    FOR temp_var IN SELECT * FROM unnest(input_array) 
    LOOP
        RETURN NEXT temp_var.message;
    END LOOP;
    RETURN;
END
$BODY$ LANGUAGE plpgsql;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM