Postgresql
在 FOR 循環中分配多個變數的結果令人驚訝
CREATE OR REPLACE FUNCTION my_function(input jsonb) RETURNS jsonb LANGUAGE plpgsql AS -- language declaration required $func$ DECLARE _key text; _value text; BEGIN FOR _key, _value IN SELECT jsonb_each_text($1) LOOP -- do some math operation on its corresponding value RAISE NOTICE '%: %', _key, _value; END LOOP; RETURN input; END $func$;
對於函式,如果我呼叫:
my_function('{"a":1, "b":2}');
它將在消息框中發出類似於 (a, 1), (b, 2) 的通知。
但是,如果我更改程式碼:
RAISE NOTICE '%: %', _key, _value;
進入:
RAISE NOTICE '%', _key;
會彈出相同的結果。
雖然程式碼:
RAISE NOTICE '%', _value;
什麼都不會彈出。那是怎麼發生的?
我想我應該為這種混亂負責。
程式碼範例來自我對您之前的問題的回答,其中有一個微妙的錯誤(現已修復)。
出了什麼問題?
jsonb_each_text()
是一個集合返回函式,它返回一組行。呼叫時:SELECT * FROM jsonb_each_text('{"a":1, "b":2}')
它返回:
關鍵 | 價值 -----+------- 一個 | 1 乙 | 2
但是當像上面這樣呼叫時:
SELECT jsonb_each_text('{"a":1, "b":2}')
它返回:
jsonb_each_text ----------------- (a,1) (b,2)
每行都返回一個值,即行值,其文本表示形式與顯示的一樣。
現在,分配:
FOR _key, _value IN SELECT jsonb_each_text($1) ...
將每行的第一個值分配給提供的第一個變數,
_key
在範例中。行值text
在賦值中被強制轉換。由於沒有第二個值,_value
因此設置為NULL
。所以,後者:RAISE NOTICE '%: %', _key, _value;
輸出消息:
注意:(a,1): <NULL> 注意:(b,2):<NULL>
這可能會產生誤導。(但請注意懸空
: <NULL>
!)改成:
FOR _key, _value IN SELECT * FROM jsonb_each_text($1)
.. 迷霧應該會散去。