如何使用PostgreSQL函数获取多个结果集

3

我想使用函数返回多个结果集,但是 reader.NextResult() 不起作用。查询结果如下:

"<unnamed portal 1>"
"<unnamed portal 2>"

函数(存储过程),PostgreSQL

CREATE OR REPLACE FUNCTION public.sp_get_multiviewlist
( )
RETURNS SETOF refcursor
DECLARE
    ref1 refcursor;
    ref2 refcursor;
BEGIN
OPEN ref1 FOR
SELECT * FROM public."Customer";
RETURN NEXT ref1;

OPEN ref2 FOR 
SELECT * FROM public."Order";
RETURN NEXT ref2;

END;

$$ LANGUAGE plpgsql;

其他数据库可以正常工作,我该怎么做呢?
npgsql:版本3.2.5
1个回答

4
使用setof refcursor是一种在PG中模拟多个结果集的方法。但它实际上并不同于多个结果集。
Npgsql曾经自动获取存储过程返回的游标内容,但这并不总是符合预期,因此已将其删除。可以在此Github问题中阅读整个(长)讨论。
无论如何,要获取数据,必须执行FETCH ALL FROM "<unnamed portal 1>" - 其中unnamed portal 1必须是存储过程返回的字符串。只有在事务内执行存储过程,游标才能保持足够长的生命周期。
您可以查看Npgsql以前的做法此处,或者按照以下通用方法进行操作:
using(var trans = db.BeginTransaction())
using(var cmd = db.CreateCommand()) {           
    cmd.CommandText = "sp_get_multiviewlist";
    cmd.CommandType = CommandType.StoredProcedure;  

    string cursor1Name,cursor2Name;
    using (var reader = cmd.ExecuteReader())
    {
        reader.Read();
        cursor1Name = reader.GetString(0);
        reader.Read();
        cursor2Name = reader.GetString(0);
    }


    using(var resultSet1 = db.CreateCommand())
    {
        resultSet1.CommandText = $@"FETCH ALL FROM ""{cursor1Name}""";
        using (var reader = resultSet1.ExecuteReader())
        {
            while (reader.Read())
            {
                // Do something with the customer row
            }
        }
    }

    using (var resultSet2 = db.CreateCommand())
    {
        resultSet2.CommandText = $@"FETCH ALL FROM ""{cursor2Name}""";
        using (var reader = resultSet2.ExecuteReader())
        {
            while (reader.Read()) {
                // Do something with the order row
            }
        }
    }
}

谢谢,但我遇到了一个错误:Npgsql.PostgresException: '34000: 游标"<未命名门户2>"不存在'。怎样才能使用固定的refcursor名称? - Korkut Düzay
很确定你没有使用事务,就像我说的那样。如果你没有使用事务,那么光标在关闭第一个读取器时就停止存在了(或者甚至在此之前?不太确定)。 - gnud
是的,只有在事务中才能工作。这是一个困难的解决方案,但我很高兴它还是得以解决。我将运行该项目。再次感谢。 - Korkut Düzay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接