我正在将 MSSQL 数据库迁移到 PostgreSql。 MSSQL db 有一个返回多个结果集的存储过程。为了将其迁移到 Postgres,我将 refcursors 作为参数传入以检索多个结果集,例如
CREATE OR REPLACE PROCEDURE public.test_proc(IN par_id bigint, INOUT ref_cur1 refcursor, INOUT ref_cur2 refcursor)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
OPEN ref_cur1 FOR
SELECT * From firsttable where firsttable.id = par_id;
OPEN ref_cur2 FOR
SELECT * from secondtable where lnkid = par_id;
END;
$BODY$;
我正在尝试使用 Npgsql 在我的 .net 应用程序中调用该存储过程
using (var lConn = GetConnection()) {
using (var trans = lConn.BeginTransaction()) {
using (var cmd = GetCommand("call public.test_proc(@par_id, @ref_cur1, @ref_cur2)", lConn, trans, System.Data.CommandType.Text)) {
cmd.Parameters.Add("@par_id", NpgsqlDbType.Integer).Value = id;
cmd.Parameters.Add(new NpgsqlParameter() {
ParameterName = "@ref_cur1",
NpgsqlDbType = NpgsqlDbType.Refcursor,
Value = "ref_cur1",
Direction = System.Data.ParameterDirection.InputOutput
});
cmd.Parameters.Add(new NpgsqlParameter() {
ParameterName = "@ref_cur2",
NpgsqlDbType = NpgsqlDbType.Refcursor,
Value = "ref_cur2",
Direction = System.Data.ParameterDirection.InputOutput
});
cmd.ExecuteNonQuery();
cmd.CommandText = $"fetch all \"ref_cur1\"";
cmd.CommandType = CommandType.Text;
var reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
string name = (string)reader["name"];
DateTime dtTime = (DateTime)reader["createddate"];
}
}
reader.Close();
cmd.CommandText = $"fetch all \"ref_cur2\"";
cmd.CommandType = CommandType.Text;
reader = cmd.ExecuteReader(); //This throws exception
if (reader.HasRows)
{
while (reader.Read())
{
string name = (string)reader["description"];
int lnkId = (int)reader["lnkid"];
}
}
reader.Close();
}
}
}
我能够读取 ref_cur1 的值,但在尝试检索第二个光标时出现以下异常
<块引用>无法使用处理程序类型 TextHandler 编写 CLR 类型 System.Int64
我是 postgres 的新手,上面的大部分 sql 和代码来自不同的谷歌搜索,所以如果有更好的方法从 SP 返回多个结果,请告诉我。
答案 0 :(得分:0)
我无法使用存储过程进行处理,因此最终恢复使用函数,为此相同的 Npgsql 代码成功获取了多个游标。我唯一需要做的改变就是使用
<块引用>var cmd = GetCommand("public.test_proc"
用于函数而不是
<块引用>var cmd = GetCommand("调用 public.test_proc(@par_id, @ref_cur1, @ref_cur2)"
用于存储过程
感谢@ShayRojansky 的协助。