Использование setof refcursor
- это способ эмулировать несколько наборов результатов в PG.Но на самом деле это не то же самое, что множественные результирующие наборы.
Npgsql, используемый для автоматической выборки содержимого курсоров, возвращаемых из хранимых процедур, но это также не всегда ожидалось, поэтому он был удален.Прочитайте всю (долгую) дискуссию на этой проблеме github .
В любом случае, чтобы получить данные, вы должны выполнить FETCH ALL FROM "<unnamed portal 1>"
- где unnamed portal 1
должна быть строкой, возвращенной из сохраненногоProc.Курсоры останутся в живых достаточно долго, если вы выполните хранимую процедуру внутри транзакции.
Вы можете посмотреть, как 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
}
}
}
}