摘要:DWS的PL/pgSQL函數/存儲過程中有一個特殊的語法PERFORM語法,用於執行語句但是丟棄執行結果的場景,常用於一些狀態判斷的場景。 本文分享自華為雲社區《GassDB(DWS)功能 -- 函數出參 #【玩轉PB級數倉GaussDB(DWS)】》,作者:譡里個檔。 DWS的PL/pgSQ ...
摘要:DWS的PL/pgSQL函數/存儲過程中有一個特殊的語法PERFORM語法,用於執行語句但是丟棄執行結果的場景,常用於一些狀態判斷的場景。
本文分享自華為雲社區《GassDB(DWS)功能 -- 函數出參 #【玩轉PB級數倉GaussDB(DWS)】》,作者:譡里個檔。
DWS的PL/pgSQL函數/存儲過程中有一個特殊的語法PERFORM語法,用於執行語句但是丟棄執行結果的場景,常用於一些狀態判斷的場景。但是客戶往往會不當使用PERFORM語法,導致業務邏輯出錯,最常見的就是使用PERFORM執行帶有出參的函數。
已知函數inner定義如下
CREATE OR REPLACE FUNCTION public.inner( IN a1 integer, IN b1 integer, OUT a integer, OUT b integer ) RETURNS record LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE BEGIN a := a1; b := b1; END$function$ ;
函數f_outer定義如下,函數體中調用函數inner,把函數的出參賦值給變數a, b
CREATE OR REPLACE FUNCTION public.f_outer(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int; b int; BEGIN PERFORM public.inner(i_a, i_b, a, b); RAISE INFO 'a = %, b = %', a, b; END$function$ ;
但是實際執行的時候發現函數inner的出參沒有正確賦值(預期值為a = 1 b = 11)。
postgres=# CALL f_outer(1, 11); INFO: a = <NULL>, b = <NULL> SQLSTATE: 00000 f_outer --------- (1 row) Time: 1.086 ms
出現這種問題的原因是PERFORM語法會執行SQL語句,但是會拋棄執行結果,導致函數出參沒有賦值
DWS中常用的帶出函數出參的方式有以下三種:
- 方式1:函數出參的方式賦值
CREATE OR REPLACE FUNCTION public.test1(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int; b int; BEGIN public.inner(i_a, i_b, a, b); RAISE info 'a = %, b = %', a, b; END$function$ ;
- 方式2:動態查詢語句方式賦值
CREATE OR REPLACE FUNCTION public.test2(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int; b int; BEGIN EXECUTE IMMEDIATE 'SELECT * from public.inner(:1, :2)' UNSING INTO a, b USING IN i_a, i_b; RAISE INFO 'a = %, b = %', a, b; END$function$ ;
- 方式3:SELECT .. INTO賦值
CREATE OR REPLACE FUNCTION public.test3(IN i_a int, IN i_b int) RETURNS void LANGUAGE plpgsql NOT FENCED NOT SHIPPABLE AS $function$ DECLARE a int := 0; b int := 0; BEGIN SELECT * INTO a, b FROM public.inner(i_a, i_b); RAISE INFO 'a = %, b = %', a, b; END$function$ ;