Копировать Occi:: ResultSet перед закрытием Occi:: Connection


Я использую OCCI с C++ для получения данных от Oracle. Код работает хорошо, однако я заметил некоторое снижение производительности. Это происходит потому, что в итерации rset->next() некоторое вычисление занимает время. Влияние этой задержки заключается в том, что пул соединений oracle имеет одно соединение занято. Если одновременные запросы требуют одного и того же вычисления, возможно, все соединения в пуле будут заняты.

     Statement *stmt = conn->createStatement (sqlQuery);

      ResultSet *rset = stmt->executeQuery ();
      while (rset->next ())
      {
        //Slow computation takes time
        compute()
      }

      stmt->closeResultSet (rset);

      conn->terminateStatement (stmt);
      env->terminateConnection (conn);

Итак, мой вопрос: Могу ли я скопировать Occi:: ResultSet (используя общий указатель?) в порядке чтобы закрыть соединение после копирования и выполнить вычисления после освобождения соединения?

go_to_oracle( ResultSet &result) {
 Statement *stmt = conn->createStatement (sqlQuery);

  ResultSet *rset = stmt->executeQuery ();

  copy_rset_to_result;


  stmt->closeResultSet (rset);

  conn->terminateStatement (stmt);
  env->terminateConnection (conn);
}

my_method() {

 ResultSet *result = NULL
 go_to_oracle(result);
 //here connection is closed, but we have the data
 compute(result) // do this without have connection occupied

}

Есть ли примеры, доступные на GitHub?

2 6

2 ответа:

Невозможно закрыть соединение с базой данных и сохранить результирующий набор (occi::ResultSet) для последующего использования. Одна из причин заключается в том, что occi::ResultSet::next извлекает данные из базы данных. Вместо этого вы можете использовать выборку массива и буфер данных, выделенный Пользователем для хранения результатов.

Пример использования occi:: ResultSet:: setDataBuffer:

oracle::occi::ResultSet* rs=nullptr;
//.....
// query
//.....
static const size_t max_numrows=5000;
char var_buf[max_numrows][7];
char sym_buf[max_numrows][9];
rs->setDataBuffer(1,var_buf,oracle::occi::OCCI_SQLT_STR,sizeof(var_buf[0]),(ub2*)0);
rs->setDataBuffer(2,sym_buf,oracle::occi::OCCI_SQLT_STR,sizeof(sym_buf[0]),(ub2*)0);
size_t fetch_count=0;
while(rs->next(max_numrows)==ResultSet::DATA_AVAILABLE)
{
    /* This would probably be an error as you would like
       the whole result to fit in the data buffer.*/
}
stmt->closeResultSet (rs);
conn->terminateStatement (stmt);
compute(var_buf,sym_buf);

Обратите внимание, что массив fetch действует как prefetch в этом

Status next(
   unsigned int numRows =1);

Получает до numRows за вызов.

Выполнение запроса не возвращает данные. Вы считываете данные с сервера, используя rset - >next (). Итак, если вы прервете соединение - вы не сможете прочитать данные