一文詳解數倉GaussDB(DWS) 函式出參帶出方式

華為雲開發者聯盟發表於2023-02-10
摘要:本文主要講解DWS函式出參帶出方式。

本文分享自華為雲社群《GaussDB(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$
;

 

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章