2017-10-11 26 views
6

Używam OCCI z C++, aby uzyskać dane z Oracle. Kod działa dobrze, ale zauważyłem spadek wydajności. Dzieje się tak, ponieważ w czasie wykonywania rset-> next() niektóre obliczenia wymagają czasu. Wpływ tego opóźnienia polega na tym, że pula połączeń Oracle ma zajęte jedno połączenie. Jeśli jednocześnie żądania wymagają tego samego obliczenia, być może wszystkie połączenia w puli będą BUSY.Kopiuj Occi :: ResultSet przed zamknięciem Occi :: Connection

 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); 

Więc moje pytanie brzmi: Czy mogę skopiować occi :: ResultSet (za pomocą udostępnionego wskaźnik?), Aby zamknąć połączenie po egzemplarzu i wykonać obliczenia po zwolnieniu połączenia?

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 

} 

Wszelkie przykłady dostępne na GitHub?

+0

Jeśli jest to możliwe, utwórz obiekt klasy i zapisz każdą surową informację w obiekcie klasy i zapisz ją na mapie. Zrób to po załadowaniu programu. –

Odpowiedz

1

Nie można zamknąć połączenia z bazą danych i zapisać zestawu wyników (occi :: ResultSet) do późniejszego wykorzystania. Jednym z powodów jest to, że occi :: ResultSet :: next pobiera dane z bazy danych. Zamiast tego możesz użyć pobierania tablicy i przydzielonego przez użytkownika bufora danych do przechowywania wyników.

Przykład zastosowania 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); 

Należy zauważyć, że tablica pobierania działa jak pobierania wstępnego w tym

Status next(
    unsigned int numRows =1); 

pobiera się do NumRows na wezwanie.

+0

Jeśli jest to możliwe, utwórz obiekt klasy i zapisz każdą surową informację w obiekcie klasy i zapisz ją na mapie. Zrób to po załadowaniu programu. –

-1

Wykonanie zapytania nie pobiera danych. Odczytujesz dane z serwera za pomocą opcji rset-> next(). Tak więc, jeśli zakończysz połączenie - nie można odczytać danych

+0

Wiem o tym. Szukam rozwiązania, które pobiera cały zestaw wyników bez wykonywania obliczeń, zamknij połączenie i sprawdź poprawność zestawu wyników później. – cateof

Powiązane problemy