2014-04-03 17 views
5

mi piacerebbe chiamare una stored procedure , che ha un parametro di tipo TABLE.
Come posso fare questo utilizzando (11g1) in un'applicazione Windows C++?Come chiamare una stored procedure con un parametro di tipo di tabella

Ecco la definizione della stored procedure:

FUNCTION am_send(
    p_caFnr     IN  VARCHAR2, 
    p_TabBgr     IN  DSKS_BGR_TAB, 
    p_caTextout    OUT  VARCHAR2) 
    RETURN NUMBER; 

e le tipologie utilizzate:

create or replace 
TYPE  DSKS_BGR_TAB, 
AS TABLE OF DSKS_BGR 

create or replace 
TYPE  DSKS_BGR 
(BgrNr VARCHAR2(3), 
TrId  VARCHAR2(8)) 

quello che ho fatto finora:

ho creato un rappresentazione dell'oggetto di tipo DSKS_BGR utilizzando th e OTT Utility.

Il mio codice finora:

Environment* env = Environment::createEnvironment(Environment::OBJECT); 

try 
{ 
    Connection *con = env->createConnection("xxxxx", "xxxxx", "xxxxx"); 

    Statement* statement = con->createStatement("BEGIN :1 := am_send(:2, :3, :4); END;"); 

    statement->registerOutParam(1, OCCINUMBER); 
    statement->setString(2, "Test");  
    // ?? DSKS_BGR_TAB 
    statement->registerOutParam(4, OCCISTRING, 1000); 

    statement->execute(); 

    int result = statement->getNumber(1); 
    string textOut = statement->getString(4); 

    env->terminateConnection(con); 
} 
catch(const SQLException &exc) 
{ 
    cout << exc.getErrorCode() << exc.getMessage(); 
} 

Environment::terminateEnvironment(env); 

non ho idea di come impostare il parametro TABLE.

risposta

7

Sei quasi arrivato!

  1. creare rappresentazioni oggetto della vostra tipi Oracle utilizzando l'utilità di tipo traduttore oggettoOTT

  2. Creare un vector di puntatori al OTT tipo creato e utilizzare la chiamata OCCI setVector() sulla dichiarazione

  3. Execute!

Ecco un piccolo esempio di codice:

#include <occi.h> 
#include <iostream> 
#include "RegisterMappings.h" 

using namespace oracle::occi; 
using namespace std; 

void callproc(Connection *con) 
{ 
    vector<my_obj_t *> vect; 
    int i; 
    for (i=0; i<10; i++) 
    {  
     my_obj_t *obj = new my_obj_t();  
     obj->setid(i); 
     obj->setname("TEST"); 
     vect.push_back(obj); 
    } 
    cout << "\ncallproc - invoking a PL/SQL procedure with parameters" << endl; 
    Statement *stmt = con->createStatement("BEGIN my_proc(:1); END;"); 
    cout << "\nExecuting the block :" << stmt->getSQL() << endl; 
    setVector(stmt, 1, vect, "MY_OBJ_TAB_T"); 
    stmt->execute(); 
    con->terminateStatement (stmt); 

    cout << "\nocciproc - done" << endl; 

    // delete allocated memory 
    for (i=0; i<10; i++) 
    {  
     delete vect[i]; 
    } 
} 
// end of callproc() 
int main() 
{ 
try { 
    Environment* env = Environment::createEnvironment(Environment::OBJECT); 
    RegisterMappings(env); 
    Connection* conn = env->createConnection("scott","tiger"); 
    callproc(conn); conn->commit(); 
    env->terminateConnection(conn); 
    Environment::terminateEnvironment(env); 
    } 
    catch(SQLException &ex) 
    { 
     cout << ex.getMessage() << endl; 
    } 
} 
+2

Penso che ci sarà una perdita di memoria - è necessario liberare manualmente la memoria con delete per ogni elemento nel vettore. Io so che è un buon esempio, solo che ho perso così tanto tempo a cercare perdite di memoria ultimamente, mi dispiace per essere fastidioso:/ – user1645975

+0

@ user1645975: Hai perfettamente ragione: c'era una perdita di memoria nell'esempio sopra. Fisserò il codice di esempio (ufficiale oracolo) qui sopra. –

+0

Sì, mi ricordo quegli esempi, alcuni anni fa, quando non avevo idea di perdite di memoria e di come stavo pensando: "sicuramente non ci può essere un errore qui, è un esempio ufficiale ..." – user1645975

Problemi correlati