首页 > 解决方案 > 如何从 PostgreSQL 12.5 版本的存储过程中获取多个结果集?

问题描述

表创建

CREATE TABLE schname.newtable ( id serial NOT NULL, 
    username varchar(100) NULL,
    inserted_on varchar NULL DEFAULT now() );

程序创建

CREATE OR REPLACE PROCEDURE schname.pr_insertion(p_type integer, p_name character varying, INOUT p_cur refcursor DEFAULT 'kkk'::refcursor)
 LANGUAGE plpgsql
AS $procedure$
declare  
    err_context text;
begin 
    begin 

if p_type = 1 then   
    insert into schname.newtable (username) values (p_name) ;

    open p_cur for select  id, username, inserted_on FROM schname.newtable ;
end if ;  

exception  
    when others then
    rollback;
        GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT;
        RAISE INFO 'Error Name:%',SQLERRM;
        RAISE INFO 'Error State:%', SQLSTATE;
        RAISE INFO 'Error Context:%', err_context;

       insert into schname.lms_proc_error_log (function_name, ptype, module1, error_number, error_state, error_context)
       select 'pr_insertion', p_type, 'Login-check', cast(sqlerrm as varchar) , cast(sqlstate as varchar)  , err_context ;  

        open p_cur for 
        select sqlerrm || ' fail' || err_context as status ;

end; 
  commit; 

end ;
$procedure$
;

在查询窗口中执行/调用上述存储过程时出现以下错误

 call schname.pr_insertion(1, 'h') ;
 FETCH ALL FROM "kkk" ;
    

错误:SQL 错误 [34000]:错误:游标“kkk”不存在

注意:如果我在查询下方运行记录正在插入,但我们无法获取结果集

 call schname.pr_insertion(1, 'h') ;
    FETCH ALL FROM "kkk" ;

标签: postgresql

解决方案


游标仅在事务期间存在,因此您必须将两个语句包装在事务中:

BEGIN;
CALL schname.pr_insertion(1, 'h');
FETCH ALL FROM kkk;
COMMIT;

此外,像您正在做的那样使用相同的光标来显示错误消息并不是一个聪明的主意。使用函数并将消息作为函数结果,或者INOUT为消息使用另一个参数。


推荐阅读