我遇到了另一个问题,即在一个带有多个ref游标的sproc周围使用数据读取器。我得到一个不受支持的例外。不幸的是,我可以从npgsql的源代码中看到它来自哪里..我不确定我是否同意抛出该异常。我们编写的代码与oracle(完全托管和托管的版本),sql server一起使用。任何帮助都可以帮助保持它与某些关键的dbms风格的api保持一致。
sproc body
CREATE OR REPLACE FUNCTION public.getmultipleresultsets (
v_organizationid integer)
RETURNS Setof refcursor
LANGUAGE 'plpgsql'
AS $BODY$
declare public override void AddCursorOutParameter(DbCommand command,
string RefCursorName)
{
NpgsqlParameter parameter = (NpgsqlParameter)CreateParameter(RefCursorName, false);
parameter.NpgsqlDbType = NpgsqlDbType.Refcursor;
parameter.NpgsqlValue = DBNull.Value;
parameter.Direction = ParameterDirection.Output;
command.Parameters.Add(parameter);
}
cv_1 refcursor;
cv_2 refcursor;
BEGIN
open cv_1 for
SELECT a.errorCategoryId, a.name, a.bitFlag
FROM ErrorCategories a
ORDER BY name;
RETURN next cv_1;
open cv_2 for
SELECT *
FROM StgNetworkStats ;
RETURN next cv_2;
END;
$BODY$;
包装postgres sql的密钥阅读器代码(npgsql的Entlib实现)
private IDataReader DoExecuteReader(DbCommand command, CommandBehavior cmdBehavior)
{
try
{
var sql = new StringBuilder();
using (var reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
sql.AppendLine($"FETCH ALL IN \"{ reader.GetString(0) }\";");
}
}
command.CommandText = sql.ToString();
command.CommandType = CommandType.Text;
IDataReader reader2 = command.ExecuteReader(cmdBehavior);
return reader2;
}
catch (Exception)
{
throw;
}
}
命令构建代码如下所示
Helper.InitializeCommand(cmd, 300, "getmultipleresultsets");
db.AddReturnValueParameter(cmd);
db.AddInParameter(cmd, "organizationId", DbType.Int32, ORGANIZATIONID);
db.AddCursorOutParameter(cmd, "CV_1");
db.AddCursorOutParameter(cmd, "CV_2
添加refcursor参数的代码就是这样的
答案 0 :(得分:0)
上面的代码似乎使用.NET客户端代码试图读取其结果而使PostgreSQL函数变得混乱。
无论如何,声明你的函数返回一组 个refcursors - 这与两个输出参数不同;你似乎混淆了光标的名称(游标有名字,但不是整数,例如)和参数的名称(int参数确实有名字)。
请注意,PostgreSQL实际上没有输出参数 - 函数总是返回一个表,而这就是它。 PostgreSQL确实有一个带输出参数的函数语法,但这只是构造输出表模式的一种方法。这与SQL Server不同,后者显然可以返回表和一组命名输出参数。为了便于移植,在读取结果时,如果Npgsql看到任何带有方向输出的NpgsqlParameter,它将尝试查找带有参数名称的结果集,并简单地用第一行的值填充NpgsqlParameter的值该专栏。这种做法与简单地自己阅读结果集相比没有增加价值 - 它只是为了兼容性。
总结一下,我建议您与读者一起阅读反馈器,然后根据需要获取结果。