如何从 C# 中的 plpgsql 函数 return refcursor?
How to return refcursor from plpgsql function in c#?
我是 plpgsql 的新手,我创建了一个存储过程来将 table 数据导入 refcursor,我正尝试从 plpgsql 和 c# 调用该过程来检查 procedure/c# 代码工作正常。
程序:
CREATE OR REPLACE FUNCTION public.proc_get_test(out tbldata refcursor)
returns refcursor
LANGUAGE plpgsql
AS $function$
BEGIN
open tbldata for
select * from arc_mmstbrndgroup;
END;
$function$;
从 plpgsql 调用过程:
SELECT proc_get_test('cur');
输出:
然后尝试从 refcursor 获取数据:
FETCH ALL FROM cur;
SQL Error [34000]: ERROR: cursor " cur " does not exist
另一种尝试方式:
BEGIN;
SELECT proc_get_test('cur');
FETCH ALL FROM cur;
COMMIT;
输出:
C#:
var p = new PostgreSQLDynamicParameters();
p.Add("tbldata", dbType: NpgsqlDbType.Refcursor, direction: ParameterDirection.Output);
using (var multi = _connection.QueryMultiple("proc_get_test", param: p, commandType: CommandType.StoredProcedure))
{
List<PostgresModel> dataMaster = multi.Read<PostgresModel>().AsList();
return new ResponseModel { ResultSet = dataMaster, StatusCode = 1, StatusDescription = "Success" };
}
Api 只收到 1 行也有空值
任何人都可以帮助我在 plpgsql 和 c# 中调用过程吗?
所以我尝试在 plpgsql 中创建一个带有多个 refcursor 的演示函数,如下所示:
CREATE OR REPLACE FUNCTION public.proc_get_multiple_cursors_test()
returns setof refcursor
LANGUAGE plpgsql
AS $$
DECLARE
ref1 refcursor:= 'ref1';
ref2 refcursor:= 'ref2';
BEGIN
open ref1 for
select * from arc_mmstbrndgroup;
return next ref1;
open ref2 for
select * from arc_mmstbrndgroup;
return next ref2;
END;
$$
并从 c# 中调用此函数,如下所示:
_connection.Open();
NpgsqlTransaction trans = _connection.BeginTransaction();
using (var multi = _connection.QueryMultiple("proc_get_multiple_cursors_test", null, transaction: trans, commandType: CommandType.StoredProcedure))
{
var result = multi.Read();
var ref1 = _connection.QueryMultiple("FETCH ALL IN ref1", null, commandType: CommandType.Text, transaction: trans);
List<PostgresModel> dataMaster = ref1.Read<PostgresModel>().AsList();
var ref2 = _connection.QueryMultiple("FETCH ALL IN ref2", null, commandType: CommandType.Text, transaction: trans);
List<PostgresModel> dataMaster2 = ref2.Read<PostgresModel>().AsList();
trans.Commit();
_connection.Close();
return new ResponseModel
{
ResultSet = new
{
master1 = dataMaster,
master2 = dataMaster2
},
StatusCode = 1,
StatusDescription = "Success"
};
}
现在它返回两个游标的输出
我是 plpgsql 的新手,我创建了一个存储过程来将 table 数据导入 refcursor,我正尝试从 plpgsql 和 c# 调用该过程来检查 procedure/c# 代码工作正常。
程序:
CREATE OR REPLACE FUNCTION public.proc_get_test(out tbldata refcursor)
returns refcursor
LANGUAGE plpgsql
AS $function$
BEGIN
open tbldata for
select * from arc_mmstbrndgroup;
END;
$function$;
从 plpgsql 调用过程:
SELECT proc_get_test('cur');
输出:
然后尝试从 refcursor 获取数据:
FETCH ALL FROM cur;
SQL Error [34000]: ERROR: cursor " cur " does not exist
另一种尝试方式:
BEGIN;
SELECT proc_get_test('cur');
FETCH ALL FROM cur;
COMMIT;
输出:
C#:
var p = new PostgreSQLDynamicParameters();
p.Add("tbldata", dbType: NpgsqlDbType.Refcursor, direction: ParameterDirection.Output);
using (var multi = _connection.QueryMultiple("proc_get_test", param: p, commandType: CommandType.StoredProcedure))
{
List<PostgresModel> dataMaster = multi.Read<PostgresModel>().AsList();
return new ResponseModel { ResultSet = dataMaster, StatusCode = 1, StatusDescription = "Success" };
}
Api 只收到 1 行也有空值
任何人都可以帮助我在 plpgsql 和 c# 中调用过程吗?
所以我尝试在 plpgsql 中创建一个带有多个 refcursor 的演示函数,如下所示:
CREATE OR REPLACE FUNCTION public.proc_get_multiple_cursors_test()
returns setof refcursor
LANGUAGE plpgsql
AS $$
DECLARE
ref1 refcursor:= 'ref1';
ref2 refcursor:= 'ref2';
BEGIN
open ref1 for
select * from arc_mmstbrndgroup;
return next ref1;
open ref2 for
select * from arc_mmstbrndgroup;
return next ref2;
END;
$$
并从 c# 中调用此函数,如下所示:
_connection.Open();
NpgsqlTransaction trans = _connection.BeginTransaction();
using (var multi = _connection.QueryMultiple("proc_get_multiple_cursors_test", null, transaction: trans, commandType: CommandType.StoredProcedure))
{
var result = multi.Read();
var ref1 = _connection.QueryMultiple("FETCH ALL IN ref1", null, commandType: CommandType.Text, transaction: trans);
List<PostgresModel> dataMaster = ref1.Read<PostgresModel>().AsList();
var ref2 = _connection.QueryMultiple("FETCH ALL IN ref2", null, commandType: CommandType.Text, transaction: trans);
List<PostgresModel> dataMaster2 = ref2.Read<PostgresModel>().AsList();
trans.Commit();
_connection.Close();
return new ResponseModel
{
ResultSet = new
{
master1 = dataMaster,
master2 = dataMaster2
},
StatusCode = 1,
StatusDescription = "Success"
};
}
现在它返回两个游标的输出