Может ли кто-нибудь показать мне рабочий пример использования курсора, возвращаемого из PLSQL в код С#? Я нашел много примеров, показывающих, как заполнить 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);
tr.Commit();
when I wrote 'fetch' after sql command it works but it is not suitable.
thnx in advance
У меня есть ответы на мой вопрос.
Проблема: Я сохранил процедуру PLSQL, которая возвращает refCursor. Мне нужно вернуть данные с помощью 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 позаботится о правильном привязке ваших параметров.
Но теперь у меня другая проблема. Когда я передаю только один выходной параметр в свой командный текст. В результате у меня есть поля, один из которых равен 0 {мой первый выходной параметр} другой В oracle я могу напрямую преобразовать параметр RefCursor в datareader, но в postgresql я не могу.
Спасибо за внимание
для справки
/// <summary>
/// Get data from the returning refcursor of postgresql function
/// </summary>
/// <param name="FunctionName">Function name of postgresql</param>
/// <param name="Parameters">parameters to pass to the postgresql function</param>
/// <param name="ErrorOccured">out bool parameter to check if it occured error</param>
/// <returns></returns>
public List<DataTable> GetRefCursorData(string FunctionName, List<object> Parameters, out bool ErrorOccured)
{
string connectstring = ""; //your connectstring here
List<DataTable > dtRtn =new List<DataTable>();
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<DataTable> ,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;
}
Проблема с параметром Out Я решил использовать две команды в одной транзакции
из первой команды, которую я считываю, и выполните следующую команду
вторая команда выглядит как
var cmd2 = new NpgsqlCommand("FETCH ALL FROM \"list\"", (NpgsqlConnection) Connection)
где указано имя курсора, созданного внутри хранимой процедуры в результате получают данные, выбранные из db
Прежде всего, вот некоторые документы, которые могут быть полезны: Npgsql doc
В этой документации вы найдете NpgsqlDataAdapter. Этот объект также имеет метод Fill() (унаследованный от DbDataAdapter). Этот метод может принимать DataSet и курсор. Он будет заполнить DataSet данными, возвращаемыми вашим курсором.
Вы не можете дать DataReader этому методу, но вы можете дать DataTable, я думаю, что вам удастся что-то сделать с этим.