2017-10-11 3 views
6

J'utilise OCCI avec C++ pour obtenir des données d'Oracle. Le code fonctionne bien, mais j'ai remarqué une diminution des performances. Cela arrive parce que dans l'itération rset-> next(), certains calculs prennent du temps. L'impact de ce délai est que le pool de connexion Oracle a une connexion occupée. Si des requêtes simultanées demandent le même calcul, la connexion peut-être dans le pool sera BUSY.Copier Occi :: ResultSet avant de fermer 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); 

Donc, ma question est la suivante: Puis-je copier le Occi :: ResultSet (à l'aide d'un pointeur partagé?) Afin de fermer la connexion après la copie et faire le calcul après avoir relâché la connexion?

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 

} 

Des exemples disponibles sur GitHub? La requête d'exécution ne récupère pas les données.

+0

Si cela est possible, créez un objet de classe et stockez chaque information brute dans l'objet de classe et stockez-la dans une carte. Faites-le lorsque le programme est chargé. –

Répondre

1

Il n'est pas possible de fermer la connexion à la base de données et de sauvegarder le jeu de résultats (occi :: ResultSet) pour une utilisation ultérieure. Une raison est que occi :: ResultSet :: next récupère des données de la base de données. Au lieu de cela, vous pouvez utiliser array fetch et un tampon de données alloué par l'utilisateur pour stocker les résultats.

Exemple d'utilisation de 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); 

Notez que tableau agit comme prélecture chercher dans ce

Status next(
    unsigned int numRows =1); 

va chercher jusqu'à numRows par appel.

+0

Si c'est possible créer un objet de classe et stocker chaque information brute dans l'objet de classe et le stocker dans une carte. Faites-le lorsque le programme est chargé. –

-1

Vous lisez les données du serveur en utilisant rset-> next(). Ainsi, si vous mettez fin à la connexion - vous ne pouvez pas lire les données

+0

Je le sais. Je cherche une solution qui prend tout le resultset sans faire de calcul fermer la connection et valider le resultset plus tard – cateof