C # и PostgreSQL

2

Может ли кто-нибудь показать мне рабочий пример использования курсора, возвращаемого из 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);

what i have to write here to use NpgsqlDataReader myReader; correctly.
tr.Commit();
when I wrote 'fetch' after sql command it works but it is not suitable.

thnx in advance

  • 0
    Я думаю, что это довольно конкретный вопрос
Теги:
ado.net

4 ответа

1
Лучший ответ

У меня есть ответы на мой вопрос.

Проблема: Я сохранил процедуру 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 я не могу.

Спасибо за внимание

  • 0
    +1 именно то, что я искал.
2

для справки

    /// <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;
    }
  • 0
    Этот ответ будет более полезным, когда вы предоставите пример вызова своей функции. Например, как мы должны инициализировать параметры List <object>?
  • 0
    Есть ошибка «Команда уже выполняется:» в этой строке выполнения da.Fill (dt);
0

Проблема с параметром Out Я решил использовать две команды в одной транзакции

из первой команды, которую я считываю, и выполните следующую команду

вторая команда выглядит как


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

где указано имя курсора, созданного внутри хранимой процедуры в результате получают данные, выбранные из db

0

Прежде всего, вот некоторые документы, которые могут быть полезны: Npgsql doc

В этой документации вы найдете NpgsqlDataAdapter. Этот объект также имеет метод Fill() (унаследованный от DbDataAdapter). Этот метод может принимать DataSet и курсор. Он будет заполнить DataSet данными, возвращаемыми вашим курсором.

Вы не можете дать DataReader этому методу, но вы можете дать DataTable, я думаю, что вам удастся что-то сделать с этим.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню