Как использовать класс pqxx::stateless_cursor из libpqxx?

Я изучаю libpqxx, C++ API для PostgreSQL. Я хотел бы использовать класс pqxx::stateless_cursor, но 1) я считаю вывод Doxygen бесполезным в этом случае, и 2) веб-сайт pqxx.org уже некоторое время недоступен.

Кто-нибудь знает, как его использовать?

Я считаю, что вот как я строю один:

pqxx::stateless_cursor <pqxx::cursor_base::read_only, pqxx::cursor_base::owned>
    cursor( work, "SELECT * FROM mytable", ?, ? );

Последние два параметра называются cname и hold, но не задокументированы.

И как только курсор будет создан, как мне использовать его в цикле for() для получения каждой строки по одной?


person Stéphane    schedule 21.04.2013    source источник


Ответы (3)


Спасибо @Eelke за комментарии к cname и hold.

Я понял, как заставить pqxx::stateless_cursor работать. Я понятия не имею, есть ли более чистый или очевидный способ, но вот пример:

pqxx::work work( conn );
pqxx::stateless_cursor<pqxx::cursor_base::read_only, pqxx::cursor_base::owned>
    cursor( work, "SELECT * FROM mytable", "mycursor", false );

for ( size_t idx = 0; true; idx ++ )
{
    pqxx::result result = cursor.retrieve( idx, idx + 1 );
    if ( result.empty() )
    {
        // nothing left to read
        break;
    }

    // Do something with "result" which contains a single
    // row in this example since we told the cursor to
    // retrieve row #idx (inclusive) to idx+1 (exclusive).
    std::cout << result[ 0 ][ "name" ].as<std::string>() << std::endl;
}
person Stéphane    schedule 21.04.2013

Я не знаю библиотеку pqxx, но, основываясь на базовой команде DECLARE postgresql, я бы предположил

Это cname является именем курсора, так что это может быть любое имя, которое postgresql обычно принимает в качестве имени курсора.

Это удержание относится к опции курсора WITH HOLD из документации:

WITH HOLD указывает, что курсор можно продолжать использовать после успешной фиксации создавшей его транзакции. WITHOUT HOLD указывает, что курсор нельзя использовать вне создавшей его транзакции. Если ни WITHOUT HOLD, ни WITH HOLD не указаны, по умолчанию используется WITHOUT HOLD.

person Eelke    schedule 21.04.2013

Вот еще один пример курсора с использованием цикла do-while():

     const std::conStr("user=" + opt::dbUser + " password=" + opt::dbPasswd + " host=" + opt::dbHost + " dbname=" + opt::dbName);                                            

      pqxx::connection conn(connStr);
      pqxx::work txn(conn);
      std::string selectString = "SELECT id, name FROM table_name WHERE condition";

      pqxx::stateless_cursor<pqxx::cursor_base::read_only, pqxx::cursor_base::owned> 
      cursor(txn, selectString, "myCursor", false);

      //cursor variables
      size_t idx = 0;       //starting location
      size_t step = 10000;  //number of rows for each chunk
      pqxx::result result;
      do{
        //get next cursor chunk and update the index
        result = cursor.retrieve( idx, idx + step );
        idx += step;

        size_t records = result.size();
        cout << idx << ": records pulled = " << records << endl;

        for( pqxx::result::const_iterator row : result ){
          //iterate over cursor rows
        }
      }
      while( result.size() == step ); //if the result.size() != step, we're on our last loop
      cout << "Done!" << endl;
person shemake    schedule 17.02.2020