C#和PostgreSQL

任何人都可以向我展示使用从PLSQL返回的游标到c#代码的工作示例吗? 我发现很多例子展示了如何用返回的数据填充dataSet,但我找不到如何将该游标与DataReader一起使用,因此我有{unnamed portal}。

NpgsqlTransaction tr = (NpgsqlTransaction) Connection.BeginTransaction(); NpgsqlCommand cursCmd = new NpgsqlCommand("someStoredProcedure(:inRadius)", (NpgsqlConnection) Connection); cursCmd.Transaction = tr; NpgsqlParameter rf = new NpgsqlParameter("ref", NpgsqlTypes.NpgsqlDbType.Refcursor); rf.Direction = ParameterDirection.InputOutput; cursCmd.Parameters.Add(rf); 

我必须写这里使用NpgsqlDataReader myReader; 正确。

 tr.Commit(); 

当我在sql命令之后写’fetch’时它可以工作,但它不合适。

thnx提前

供你参考

  ///  /// Get data from the returning refcursor of postgresql function ///  /// Function name of postgresql /// parameters to pass to the postgresql function /// out bool parameter to check if it occured error ///  public List GetRefCursorData(string FunctionName, List Parameters, out bool ErrorOccured) { string connectstring = ""; //your connectstring here List dtRtn =new List(); NpgsqlConnection connection = null; NpgsqlTransaction transaction = null; NpgsqlCommand command = null; try { connection = new NpgsqlConnection(connectstring); transaction = connection.BeginTransaction(); command = new NpgsqlCommand(); command.Connection = connection; command.CommandType = CommandType.StoredProcedure; command.CommandText = FunctionName; command.Transaction = transaction; // if (Parameters != null) { foreach (object item in Parameters) { NpgsqlParameter parameter = new NpgsqlParameter(); parameter.Direction = ParameterDirection.Input; parameter.Value = item; command.Parameters.Add(parameter); } } // NpgsqlDataReader dr = command.ExecuteReader(); while (dr.Read()) { DataTable dt = new DataTable(); command = new NpgsqlCommand("FETCH ALL IN " + "\"" + dr[0].ToString() + "\"", Connection); //use plpgsql fetch command to get data back NpgsqlDataAdapter da = new NpgsqlDataAdapter(command); da.Fill(dt); dtRtn.Add(dt); //all the data will save in the List ,no matter the connection is closed or returned multiple refcursors } ErrorOccured = false; transaction.Commit(); } catch { //error handling ... ErrorOccured = true; if (transaction != null) transaction.Rollback(); } finally { if (connection != null) connection.Close(); } return dtRtn; } 

我的问题得到了一些答案。

问题:我已经存储了返回refCursor的PLSQL过程。 我必须使用datareader获取返回的数据。 但是当我添加参数db返回时

要遍历所有返回的数据,我必须编写代码,以便:

 NpgsqlTransaction tr = (NpgsqlTransaction) Connection.BeginTransaction(); NpgsqlCommand cursCmd = new NpgsqlCommand("someStoredProcedure", (NpgsqlConnection) Connection); cursCmd.Transaction = tr; NpgsqlParameter rf = new NpgsqlParameter("ref", NpgsqlTypes.NpgsqlDbType.Refcursor); rf.Direction = ParameterDirection.InputOutput; cursCmd.Parameters.Add(rf); NpgsqlParameter param2 = new NpgsqlParameter("param1", NpgsqlTypes.Int32); rf.Direction = ParameterDirection.Input; cursCmd.Parameters.Add(param2); NpgsqlDataReader r = cmd.ExecuteReader(); while (r.Read()) { ;// r.GetValue(0); } r.NextResult(); while(r.Read()) { ; } tr.Commit(); 

您应该注意到您没有在sql中编写参数,如func(:param1)

如果函数中有参数,则只将函数名称指定给CommandText属性,并像往常一样将参数添加到NpgsqlCommand.Parameters集合中。 Npgsql将正确地绑定您的参数。

但现在我有另一个问题。 当我将另一个输出参数传递给我的commandtext时。 因此我必须在其中一个字段是0 {我的第一个输出参数}另一个是在oracle中我可以直接将RefCursor参数转换为datareader但在postgresql中我不能。

感谢您的关注

Out参数问题我在同一个事务中使用两个命令解决了

从第一个命令我读出参数和执行下一个命令

第二个命令看起来像

 var cmd2 = new NpgsqlCommand("FETCH ALL FROM \"list\"", (NpgsqlConnection) Connection) 

其中列出了在存储过程中创建的游标名称,因此从db中选择了get数据

首先,这里有一些可能有用的文档 : Npgsql doc

在本文档中,您将找到NpgsqlDataAdapter。 该对象还有一个Fill()方法(inheritance自DbDataAdapter)。 此方法可以采用DataSet和游标。 它将使用游标返回的数据填充 DataSet。

您实际上无法为此方法提供DataReader,但您可以提供DataTable,我认为您可以设法对此执行某些操作。