C # и PostgreSQL - PullRequest
       42

C # и PostgreSQL

2 голосов
/ 10 января 2010

Может ли кто-нибудь показать мне рабочий пример использования курсора, возвращенного из PLSQL в код на c #? Я нашел много примеров, показывающих, как заполнить dataSet возвращенными данными, но я не могу найти, как использовать этот курсор с DataReader, в результате у меня {неназванный портал}.

<code>
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; правильно.
<code>tr.Commit();
когда я написал 'fetch' после команды sql, она работает, но она не подходит.

Заранее

Ответы [ 4 ]

3 голосов
/ 03 мая 2012

для справки

    /// <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;
    }
1 голос
/ 15 января 2010

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

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

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

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

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

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

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

0 голосов
/ 13 января 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...