Oracle has been used in the past two days, and it has been useless for a long time...
When I started to use occi for access, the code could be very streamlined, because the occi package is still very good. It is very similar to mysql ++, and I don't know who they will refer, it is easy to use.
After debugging, it was a big problem. Originally, it was a Linux platform, but it had to be switched to Windows during debugging. The problem was that occi11 and VC9 didn't seem to work together, and Environment had an error at the beginning, after a long time, I finally gave up. Test oci. Well, you can use it...
As a result, at night, I wrapped my own oci and imitated occi to make an ocipp, which is easy to use...
Here is a shame in the debugging process: when using ocipp for access, open the SQLPlus window for comparative testing. The select statement is very useful, but when using the update/delete statement, the program got stuck in the execute call. After thinking for a long time, I tried it for a long time. At half past one AM, the program got stuck and went crazy. I suddenly remembered that, by default, statements in the SQLPlus window need to be submitted by entering the commit statement, while ocipp uses the Auto-commit method, and the two should conflict. So input a commit in SQLPlus, and all pass...
So, remember, when debugging the oci interface, do not open two windows, it will be dead...
The following ocipp code is only available for viewing and is not recommended because it is not only risky but also limited. For example, ocipp only supports define and bind of the string type, because, my code only needs this type...
Ocipp. h
# Include <string>
# Include <iostream>
# Include <vector>
# Include "oci. h"
Namespace ocipp
{
Class Exception
{
Public:
Exception (int code, const std: string & msg );
Exception (int code, OCIError * err, const std: string & msg );
Void show (std: ostream & OS) const;
Protected:
Void getError (int code );
Void getError (int code, OCIError * err );
Protected:
Int _ code;
Std: string _ msg;
};
Class Connection;
Class Environment
{
Public:
Environment (unsigned int mode = OCI_DEFAULT );
Virtual ~ Environment ();
Connection * makeConnection (const std: string & user, const std: string & passwd, const std: string & server = "");
Void destroyConnection (Connection * conn );
OCIEnv * getEnv () {return _ env ;}
OCIError * getError () {return _ err ;}
Private:
Void makeEnvironment (unsigned int mode );
Protected:
OCIEnv * _ env;
OCIError * _ err;
};
Class Statement;
Class Connection
{
Friend class Environment;
Protected:
Connection (Environment * env );
Virtual ~ Connection (){}
Public:
Statement * makeStatement (const std: string & SQL );
Void destroyStatement (Statement * stmt );
Environment * getEnvironment () {return _ env ;}
OCISvcCtx * getSvc () {return _ svc ;}
Private:
Environment * _ env;
Protected:
OCIServer * _ srv;
OCISvcCtx * _ svc;
OCISession * _ auth;
};
Class Statement
{
Friend class Connection;
Protected:
Static const size_t BUF_SIZE = 256;
Struct TDefData
{
TDefData (std: string & val)
: Str (& val), buf (NULL)
{
Buf = new char [BUF_SIZE];
}
Std: string * str;
Char * buf;
};
Typedef std: vector <TDefData> TDefVector;
Protected:
Statement (Connection * conn );
Virtual ~ Statement (){}
Void syncDefVector ();
Void freeDefVector ();
Public:
Int bindString (unsigned int pos, const std: string & val );
Int defineString (unsigned int pos, std: string & val );
Int execute ();
Int getNext ();
Private:
Connection * _ conn;
Protected:
O CIStmt * _ stmt;
TDefVector _ vctDef;
};
}
Std: ostream & operator <(std: ostream & OS, const ocipp: Exception & e );
Ocipp. cpp
# Include "ocipp. h"
Namespace ocipp
{
Exception: Exception (int code, const std: string & msg)
: _ Code)
, _ Msg (msg)
{
GetError (code );
}
Exception: Exception (int code, OCIError * err, const std: string & msg)
: _ Code)
, _ Msg (msg)
{
GetError (code, err );
}
Void Exception: getError (int code)
{
Switch (code)
{
Case OCI_SUCCESS:
_ Msg = "(OCI_SUCCESS)-" + _ msg;
Break;
Case OCI_SUCCESS_WITH_INFO:
_ Msg = "(OCI_SUCCESS_WITH_INFO)-" + _ msg;
Break;
Case OCI_NEED_DATA:
_ Msg = "(OCI_NEED_DATA)-" + _ msg;
Break;
Case OCI_NO_DATA:
_ Msg = "(OCI_NODATA)-" + _ msg;
Break;
Case OCI_ERROR:
_ Msg = "(OCI_ERROR)-" + _ msg;
Break;
Case OCI_INVALID_HANDLE:
_ Msg = "(OCI_INVALID_HANDLE)-" + _ msg;
Break;
Case OCI_STILL_EXECUTING:
_ Msg = "(OCI_STILL_EXECUTE)-" + _ msg;
Break;
Case OCI_CONTINUE:
_ Msg = "(OCI_CONTINUE)-" + _ msg;
Break;
Default:
_ Msg = "(UNKNOWN)-" + _ msg;
}
}
Void Exception: getError (int code, OCIError * err)
{
GetError (code );
// If (code = OCI_ERROR)
{
Char buf [512];
OCIErrorGet (void *) err, 1, NULL, & code, (OraText *) buf, sizeof (buf), OCI_HTYPE_ERROR );
_ Msg + = "::";
_ Msg + = buf;
}
}
Void Exception: show (std: ostream & OS) const
{
OS <"[" <_ code <"]" <_ msg;
}
/**/////
Environment: Environment (unsigned int mode)
: _ Env (NULL)
, _ Err (NULL)
{
MakeEnvironment (mode );
}
Environment ::~ Environment ()
{
If (_ err! = NULL)
{
OCIHandleFree (void *) _ err, OCI_HTYPE_ERROR );
_ Err = NULL;
}
If (_ env! = NULL)
{
OCIHandleFree (void *) _ env, OCI_HTYPE_ENV );
_ Env = NULL;
}
}
Void Environment: makeEnvironment (unsigned int mode)
{
Int ret = OCIEnvCreate (& _ env, mode, NULL, 0, NULL );
If (ret! = OCI_SUCCESS | _ env = NULL)
{
Throw Exception (ret, "create Environment failed .");
}
Ret = OCIHandleAlloc (const void *) _ env, (void **) & _ err, OCI_HTYPE_ERROR, 0, NULL );
If (ret! = OCI_SUCCESS | _ env = NULL)
{
Throw Exception (ret, _ err, "create Error failed .");
}
}
Connection * Environment: makeConnection (const std: string & user, const std: string & passwd, const std: string & server)
{
Connection * conn = new Connection (this );
Int ret = OCIHandleAlloc (const void *) _ env, (void **) & (conn-> _ srv), OCI_HTYPE_SERVER, 0, NULL );
If (ret! = OCI_SUCCESS & ret! = OCI_SUCCESS_WITH_INFO) | conn-> _ srv = NULL)
{
Throw Exception (ret, "create Server failed .");
}
Ret = OCIHandleAlloc (const void *) _ env, (void **) & (conn-> _ svc), OCI_HTYPE_SVCCTX, 0, NULL );
If (ret! = OCI_SUCCESS | conn-> _ svc = NULL)
{
Throw Exception (ret, "create ScvCtx failed .");
}
Ret = OCIServerAttach (conn-> _ srv, _ err, (const OraText *) server. c_str (), server. size (), 0 );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ err, "attach Server failed .");
}
Ret = OCIAttrSet (void *) conn-> _ svc, OCI_HTYPE_SVCCTX, (void *) conn-> _ srv, 0, OCI_ATTR_SERVER, _ err );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ err, "set SVCCTX attrib failed .");
}
Ret = OCIHandleAlloc (const void *) _ env, (void **) & conn-> _ auth, OCI_HTYPE_SESSION, 0, NULL );
If (ret! = OCI_SUCCESS | conn-> _ auth = NULL)
{
Throw Exception (ret, "create Auth Session failed .");
}
Ret = OCIAttrSet (void *) conn-> _ auth, OCI_HTYPE_SESSION, (void *) user. c_str (), user. size (), OCI_ATTR_USERNAME, _ err );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ err, "set Username attrib failed .");
}
Ret = OCIAttrSet (void *) conn-> _ auth, OCI_HTYPE_SESSION, (void *) passwd. c_str (), passwd. size (), OCI_ATTR_PASSWORD, _ err );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ err, "set Password attrib failed .");
}
Ret = OCISessionBegin (conn-> _ svc, _ err, conn-> _ auth, OCI_CRED_RDBMS, OCI_DEFAULT );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ err, "Start session failed .");
}
OCIAttrSet (void *) conn-> _ svc, OCI_HTYPE_SVCCTX, (void *) conn-> _ auth, 0, OCI_ATTR_SESSION, _ err );
Return conn;
}
Void Environment: destroyConnection (ocipp: Connection * conn)
{
If (conn = NULL)
Return;
OCISessionEnd (conn-> _ svc, _ err, conn-> _ auth, OCI_DEFAULT );
OCIServerDetach (conn-> _ srv, _ err, 0 );
OCIHandleFree (void *) conn-> _ auth, OCI_HTYPE_SESSION );
OCIHandleFree (void *) conn-> _ svc, OCI_HTYPE_SVCCTX );
OCIHandleFree (void *) conn-> _ srv, OCI_HTYPE_SERVER );
Delete conn, conn = NULL;
}
/**/////
Connection: Connection (ocipp: Environment * env)
: _ Env (env)
, _ Srv (NULL)
, _ Svc (NULL)
, _ Auth (NULL)
{
}
Statement * Connection: makeStatement (const std: string & SQL)
{
Statement * stmt = new Statement (this );
Int ret = OCIHandleAlloc (const void *) _ env-> getEnv (), (void **) & (stmt-> _ stmt), OCI_HTYPE_STMT, 0, NULL );
If (ret! = OCI_SUCCESS | stmt-> _ stmt = NULL)
{
Throw Exception (ret, "create Stmt fail .");
}
Ret = OCIStmtPrepare (stmt-> _ stmt, _ env-> getError (), (const OraText *) SQL. c_str (), SQL. size (), OCI_NTV_SYNTAX, OCI_DEFAULT );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ env-> getError (), "prepare Stmt failed .");
}
Return stmt;
}
Void Connection: destroyStatement (ocipp: Statement * stmt)
{
Stmt-> freeDefVector ();
OCIHandleFree (stmt-> _ stmt, OCI_HTYPE_STMT );
Delete stmt, stmt = NULL;
}
/**/////
Statement: Statement (ocipp: Connection * conn)
: _ Conn (conn)
, _ Stmt (NULL)
{
}
Int Statement: bindString (unsigned int pos, const std: string & val)
{
OCIBind * bd = NULL;
Int ret = OCIBindByPos (_ stmt, & bd, _ conn-> getEnvironment ()-> getError (), pos, (void *) val. c_str (), val. size () + 1/** // * very dangerous */, SQLT_STR, NULL, 0, NULL, OCI_DEFAULT );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ conn-> getEnvironment ()-> getError (), "bind String failed .");
}
Return 0;
}
Int Statement: defineString (unsigned int pos, std: string & val)
{
TDefData data (val );
OCIDefine * def = NULL;
Int ret = OCIDefineByPos (_ stmt, & def, _ conn-> getEnvironment ()-> getError (), pos, (void *) data. buf, BUF_SIZE, SQLT_STR, NULL, OCI_DEFAULT );
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ conn-> getEnvironment ()-> getError (), "define String failed .");
}
_ VctDef. push_back (data );
Return 0;
}
Int Statement: execute ()
{
Unsigned short type = 0;
Int ret = OCIAttrGet (const void *) _ stmt, OCI_HTYPE_STMT, (void *) & type, 0, cursor, _ conn-> getEnvironment ()-> getError ());
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ conn-> getEnvironment ()-> getError (), "get Stmt type failed .");
}
Ret = OCIStmtExecute (_ conn-> getSvc (), _ stmt, _ conn-> getEnvironment ()-> getError (), (type! = OCI_STMT_SELECT? 1: 0), 0, NULL, NULL, OCI_COMMIT_ON_SUCCESS/** // * OCI_DEFAULT */);
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ conn-> getEnvironment ()-> getError (), "execute Stmt failed .");
}
// Unsigned int rc = 0;
// Ret = OCIAttrGet (const void *) _ stmt, OCI_HTYPE_STMT, & rc, (ub4 *) sizeof (rc), OCI_ATTR_ROW_COUNT, _ conn-> getEnvironment () -> getError ());
// If (ret! = OCI_SUCCESS)
//{
// Throw Exception (ret, _ conn-> getEnvironment ()-> getError (), "get Stmt row_count failed .");
//}
Return 0;
}
Int Statement: getNext ()
{
Int ret = OCIStmtFetch2 (_ stmt, _ conn-> getEnvironment ()-> getError (), 1, OCI_FETCH_NEXT, 1, OCI_DEFAULT );
If (ret = OCI_NO_DATA)
Return-1;
If (ret! = OCI_SUCCESS)
{
Throw Exception (ret, _ conn-> getEnvironment ()-> getError (), "fetch Stmt failed .");
}
SyncDefVector ();
Return 0;
}
Void Statement: syncDefVector ()
{
For (TDefVector: iterator it = _ vctDef. begin (); it! = _ VctDef. end (); ++ it)
{
It-> str-> assign (it-> buf, strlen (it-> buf ));
}
}
Void Statement: freeDefVector ()
{
For (TDefVector: iterator it = _ vctDef. begin (); it! = _ VctDef. end (); ++ it)
{
Delete [] it-> buf;
}
_ VctDef. clear ();
}
}
/**//////
Std: ostream & operator <(std: ostream & OS, const ocipp: Exception & e)
{
E. show (OS );
Return OS;
}