Postgresql 11 创建或替换过程 GetMultipleResultSets(INOUT ref1 refcursor, INOUT ref2 refcursor);使用 Npgsql 的自动游标引用

Postgresql 11 Create or Replace Procedure GetMultipleResultSets(INOUT ref1 refcursor, INOUT ref2 refcursor); Automatic cursor deferencing using Npgsql

要求: 如何在不使用 ado.net.

中使用 npgsql 4.0 的 fetch 语句的情况下从 postgresql 11 过程(不是函数)取回多个 refcursor 数据

这是我试过的示例:

Postgresql 程序:

CREATE OR REPLACE PROCEDURE public.GetMultipleResultSets(
    INOUT ref1 refcursor,
    INOUT ref2 refcursor)
LANGUAGE 'plpgsql'

AS $BODY$
begin
    open ref1 for
    select * from public."tblTestTable1";

    open ref2 for
    select * from public."tblTestTable2";   
end;
$BODY$;

使用 Npgsql 4.0 的 C# 代码:

    public DataSet ReturnAsDataSet(string procedureName)
    {
        this.dataSet = new DataSet();   

        OpenConnection();
        NpgsqlTransaction objTransaction = this.Connection.BeginTransaction();

        NpgsqlDataAdapter adapter = new NpgsqlDataAdapter();
        NpgsqlCommand command = this.Connection.CreateCommand();

        try
        {
            NpgsqlParameter refCursorParam1 = new NpgsqlParameter("@ref1", NpgsqlTypes.NpgsqlDbType.Refcursor);
            refCursorParam1.Direction = ParameterDirection.InputOutput;
            refCursorParam1.Value = "ref1";
            command.Parameters.Add(refCursorParam1);  

            refCursorParam2 = new NpgsqlParameter("@ref2", NpgsqlTypes.NpgsqlDbType.Refcursor);
            refCursorParam2.Direction = ParameterDirection.InputOutput;
            refCursorParam2.Value = "ref2";
            command.Parameters.Add(refCursorParam2);

            command.CommandText = "call " + procedureName + "(@ref1, @ref2)";               
            command.Transaction = objTransaction;

            adapter.SelectCommand = command;
            adapter.Fill(dataSet);          

            objTransaction.Commit();                

        }

        catch (NpgsqlException ex)
        {       
            if (objTransaction != null)                
                objTransaction.Rollback();                

            throw new Exception(ex.Message);
        }
        finally
        {
            CloseConnection();
            command.Dispose();
            objTransaction.Dispose();
        }

        return this.dataSet;
    }

此代码将 return 一个 table 具有 "ref1"、"ref2" 作为列和 "ref1" 和 "ref2" 作为值里面如下:

enter image description here

但我需要从过程中 return 编辑的实际结果集。 如果不手动获取那些 refcursor 数据,我怎样才能实现它。 我的意思是,如果不使用 "fetch all ref" 语句,我们如何通过执行上述 ExecuteReader() 或 adapter.Fill() 方法来检索数据。 npgsql 中是否有任何自动游标解除引用可用?

有知道的请提供答案。 提前感谢您的帮助。

Npgsql 目前没有为您完成此操作,this issue tracks it. You can see this long discussions on the pros and cons of this。目前,您必须自己对游标调用 FETCH。