如何用PostgreSQL写存储过程(带游标版)

CREATE OR REPLACE PROCEDURE xxx_proc(

    Ps_xxxa   varchar,  -- 参数1
    Ps_xxxb   varchar   -- 参数2

) AS $body$
DECLARE

    /*变量声明*/
    Ws_xxxa  table.column%TYPE;    -- 参数类型和某表的某字段同类型
    Ws_xxxb  varchar(10);          -- 定义长度不超10的字符串类型

    rMain RECORD;                  -- 声明游标   < 方法四>

    Wn_CNT numeric(2);             -- 循环计数器  ループカウンタ<遍历>

    Ws_SQL  TEXT;                  -- SQLコマンド用

    /*方法一:加锁游标 LOCKカーソル*/
    CurLOCK_a CURSOR (
        Ps_xxxa   varchar  -- 参数1
    ) IS
        select from where ;
    FOR UPDATE;

    /*方法二:有参数游标FETCHカーソル*/
    CurFETCH_b  CURSOR(
        Ps_xxxa   varchar  -- 参数1
    ) IS
        select from where ;

    /*方法三:无参数游标FETCHカーソル*/
    CurFETCH_c  CURSOR FOR
        select from where ;

BEGIN

    /*根据需求完善代码*/
    select  into strict  from  where ;

    delete  from  where;

    update  set  where ;

    /*方法一:打开加锁游标LOCKカーソルをオープンする*/        
    OPEN  CurLOCK_a  (  Ws_xxxa  );
        
    /*方法二:打开有参数游标FETCHカーソルをループする*/
    FOR  rMain_a  IN  CurFETCH_b  (  Ws_xxxb  ) LOOP
        select into strict from where ;
    END LOOP;

    /*方法三:打开无参数游标FETCHカーソルをループする*/
    FOR rMain_b  IN  CurFETCH_c  LOOP
        update  set  where ;                
    END LOOP;

    /*方法四:循环结果集*/
    /*!!! 注意:要声明变量(具体实例在上面的注释 <方法四> )*/
    FOR rMain IN (
        select from where ;
    ) LOOP
        insert  into  values ;
        update set where ;
    END LOOP;

    /*<遍历>  !!! 注意:要声明该变量*/
    FOR Wn_CNT IN 1..50 LOOP
        -- 一般多用于动态sql或者数组(要更新表字段是id01~id50的那种情况)
        Ws_SQL := ;
        Ws_SQL := Ws_SQL || UPDATE ;
        Ws_SQL := Ws_SQL ||     table_name ;
        Ws_SQL := Ws_SQL || SET ;
        Ws_SQL := Ws_SQL ||     (  column  ||  Wn_Cnt || ) ;
        Ws_SQL := Ws_SQL ||     = ;
        Ws_SQL := Ws_SQL ||     ( ;
        Ws_SQL := Ws_SQL ||         SELECT ;
        Ws_SQL := Ws_SQL ||             column   ||  Wn_Cnt  ;
        Ws_SQL := Ws_SQL ||         FROM ;
        Ws_SQL := Ws_SQL ||             table_name ;
        Ws_SQL := Ws_SQL ||         WHERE ;
        Ws_SQL := Ws_SQL ||             1=1 ;
        Ws_SQL := Ws_SQL ||     ) ;
        Ws_SQL := Ws_SQL || WHERE ;
        Ws_SQL := Ws_SQL ||     1=1 ;

        EXECUTE Ws_SQL::varchar;

    END LOOP;

/*异常处理*/
EXCEPTION
    WHEN OTHERS THEN
        p_end_date  :=  TO_CHAR(clock_timestamp(),YYYYMMDDHHMISS);
        p_ret_sts  :=  SQLSTATE;
        p_err_pos  :=  9999;
        p_errm   :=  SQLERRM;
END;
$body$
LANGUAGE PLPGSQL;
经验分享 程序员 微信小程序 职场和发展