⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cursor.cpp

📁 oracle引用库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#define __OCICPP_INTERNAL_USE_
#include "Cursor.h"

/*! \class OCICPP::Cursor  \brief Representation of a database cursor  This class represents a database cursor, which is used to access a set or  list of database rows from a single entity or a join of multiple entities.  A cursor may be generate by issuing for example a 'SELECT'-statement, e.g.  <pre>  SELECT OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME FROM USER_CONSTRAINTS  </pre>  An brief example:  \code   Connection con;  Connection::connect( tnsname, user, password, con);  Cursor *csr = con.execQuery("SELECT OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME FROM USER_CONSTRAINTS");  while ( csr->fetch() ) {    cout << csr->getStr( 0 ) << "." << csr->getStr( "CONSTRAINT_NAME" ) << endl;  }  \endcode  In this example, a cursor is being generated, that can be used to retreive  the four columns \c OWNER , \c CONSTRAINT_NAME , \c CONSTRAINT_TYPE ,  \c TABLE_NAME from the \c USER_CONSTRAINTS table. The columns of this cursor  may be accessed either by their ordering ( from left to right starting with   index \c 0 ) or by using their column name to index them (be sure to use  capital letters when accessing them ) *//* Construction/Destruction related methods */OCICPP::Cursor::Cursor(OCIEnv *env,OCISvcCtx *svc,OCIError *err,int prefetch,OCICPP::CursorType Type) {	init(env,svc,err,prefetch,Type);}/*!  Default Constructor: Create a cursor variable, which is not bound to any  query (yet). A cursor create in such a manner can for example be used for  Connection::execQuery(const string &,Cursor &,int)*/OCICPP::Cursor::Cursor() {	envhp=0; svchp=0; stmthp=0; paramd=0; errhp=0; nCols=0;	nulltext=default_null_text; row=0; cursorType=DEFAULT;	curRow=0; prefetchRows=0; fetched=0; fetched_all=0;}void OCICPP::Cursor::init(OCIEnv *env,OCISvcCtx *svc,OCIError *err,int prefetch,OCICPP::CursorType Type) {	envhp=env; svchp=svc; stmthp=0; paramd=0; errhp=err;curRow=0; fetched=0;	prefetchRows=prefetch; nulltext=default_null_text; row=0; nCols=0; cursorType=Type;	fetched_all=0;	//Alloc statement handle	if(cursorType!=NTABLE) {		status=OCIHandleAlloc( (dvoid *) envhp, (dvoid **) &stmthp, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);		if(status!=OCI_SUCCESS) throw OraError("Cursor: init(): Handle Alloc Failed.",OCICPPERROR);	}	Initialized=1;}/*!  Destructor */OCICPP::Cursor::~Cursor() {	drop();	}/*!  Clear the content of the cursor. This function may be used to free a cursor  variable before reusing it again. */void OCICPP::Cursor::drop() {	if(!Initialized) return;	map<string,OCIBind *>::const_iterator ci=binds.begin();	while(ci!=binds.end()) {		if(ci->second) OCIHandleFree(ci->second,OCI_HTYPE_BIND);		*ci++;		DEBUG(DLEV_DEBUG,"Bind nandle freed\n");	} 	binds.clear();	for(int i=0;i<nCols;i++) {		delete row[i];	}	cols_map.clear();	delete row;		/* We have no need to free cause it will be done in OraRefCur */	if(stmthp && cursorType!=NTABLE) OCIHandleFree(stmthp,OCI_HTYPE_STMT);	Initialized=0;}/* --------------------------------------------------- */void OCICPP::Cursor::execute(int prefetch) {	prefetchRows=prefetch;	curRow=0; fetched=0; fetched_all=0; 	for(int i=0;i<nCols;i++) delete row[i];	cols_map.clear();	delete row;			if(cursorType==DEFAULT) {		exec();	} else {		CHECKERR(errhp,OCIAttrGet(stmthp,OCI_HTYPE_STMT,(dvoid *) &stmtType,(ub4 *) 0,OCI_ATTR_STMT_TYPE,errhp));	}	DEBUG(DLEV_DEBUG,"execute(): stmtType=%d\n",stmtType);	if(stmtType==OCI_STMT_SELECT) {		describe();		define();	}}int OCICPP::Cursor::prepare(const std::string &sql) {	DEBUG(DLEV_DEBUG,"Preparing statement\n");	CHECKERR(errhp,OCIStmtPrepare(stmthp, errhp,(text *) sql.c_str() ,(ub4) strlen(sql.c_str()), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT));		CHECKERR(errhp,OCIAttrGet(stmthp,OCI_HTYPE_STMT,(dvoid *) &stmtType,(ub4 *) 0,OCI_ATTR_STMT_TYPE,errhp));	return (int)stmtType;}void OCICPP::Cursor::exec() {	DEBUG(DLEV_DEBUG,"Executing\n");	if(stmtType==OCI_STMT_SELECT) {		CHECKERR(errhp,OCIStmtExecute(svchp, stmthp,errhp,(ub4) 0,(ub4) 0, NULL, NULL, OCI_DEFAULT));	} else {		CHECKERR(errhp,OCIStmtExecute(svchp, stmthp,errhp,(ub4) 1,(ub4) 0, NULL, NULL, OCI_DEFAULT));	}}unsigned int OCICPP::Cursor::execEx() {	ub4 rows_ = 1;	ub4 rowLength_ = sizeof(rows_);	DEBUG(DLEV_DEBUG,"Executing\n");	if(stmtType==OCI_STMT_SELECT) {		CHECKERR(errhp,OCIStmtExecute(svchp, stmthp,errhp,(ub4)0,(ub4) 0, NULL, NULL, OCI_DEFAULT));	} else {		CHECKERR(errhp,OCIStmtExecute(svchp, stmthp,errhp,(ub4)1,(ub4) 0, NULL, NULL, OCI_DEFAULT));		CHECKERR(errhp,OCIAttrGet(stmthp,(ub4) OCI_HTYPE_STMT, (ub4 *)&rows_, (ub4 *) &rowLength_,				(ub4) OCI_ATTR_ROW_COUNT, (OCIError*) errhp));//            DEBUG(DLEV_FATAL,"exec(): update rows = %d\n", rows_);	}	return (unsigned int) rows_;}void OCICPP::Cursor::describe() {	DEBUG(DLEV_DEBUG,"Describing\n");	CHECKERR(errhp,OCIAttrGet(stmthp,OCI_HTYPE_STMT,(dvoid *) &nCols,(ub4 *) 0,OCI_ATTR_PARAM_COUNT,errhp));	row=new OraType*[nCols];	for(int col=0;col<nCols;col++) {		newCellByType(&(row[col]),stmthp,col);	}	if(nCols) haveResultSet=1;	hashHead();}void OCICPP::Cursor::hashHead() {	DEBUG(DLEV_DEBUG,"Mapping cols\n");	for(int col=0;col<nCols;col++) {		string attrName;		getColName(col,attrName);		cols_map[attrName]=col;	}}void OCICPP::Cursor::define() {	DEBUG(DLEV_DEBUG,"Defining output variables\n");	for(int i=0;i<nCols;i++) {		row[i]->define(stmthp,i);	}	haveResultSet=1;}	/* Binding func's */void OCICPP::Cursor::bind(const std::string &par,char *buf,int buflen,short *isNull) {	map<string,OCIBind *>::const_iterator ci=binds.find(par);	if(ci==binds.end()) {		binds[par]=0;	}  //reuse handler ... 		CHECKERR(errhp,OCIBindByName(stmthp,&(binds[par]),errhp,(CONST text *)par.c_str(),(sb4)strlen(par.c_str()),								 (dvoid *)buf,(sb4)buflen,SQLT_STR,(dvoid *)isNull,(ub2 *)0,								 (ub2 *)0,(ub4)0,(ub4 *)0,OCI_DEFAULT));	DEBUG(DLEV_DEBUG,"Bind done.param=%s,val=%s\n",par.c_str(),buf);}void OCICPP::Cursor::bind(const std::string &par,const std::string &val,short *isNull) {	map<string,OCIBind *>::const_iterator ci=binds.find(par);	if(ci==binds.end()) {		binds[par]=0;	}  //reuse handler ... 	CHECKERR(errhp,OCIBindByName(stmthp,&(binds[par]),errhp,(CONST text *)par.c_str(),(sb4)strlen(par.c_str()),								 (dvoid *)val.c_str(),(sb4)strlen(val.c_str())+1,SQLT_STR,(dvoid *)isNull,(ub2 *)0,								 (ub2 *)0,(ub4)0,(ub4 *)0,OCI_DEFAULT));	DEBUG(DLEV_DEBUG,"Bind done.param=%s,val=%s\n",par.c_str(),val.c_str());}void OCICPP::Cursor::bind(const std::string &par,int &val,short *isNull) {	map<string,OCIBind *>::const_iterator ci=binds.find(par);	if(ci==binds.end()) {		binds[par]=0;	}  //reuse handler ... 	CHECKERR(errhp,OCIBindByName(stmthp,&(binds[par]),errhp,(CONST text *)par.c_str(),(sb4)strlen(par.c_str()),								 (dvoid *)&val,(sb4)sizeof(int),SQLT_INT,(dvoid *)isNull,(ub2 *)0,								 (ub2 *)0,(ub4)0,(ub4 *)0,OCI_DEFAULT));	DEBUG(DLEV_DEBUG,"Bind done.param=%s,val=%d\n",par.c_str(),val);}void OCICPP::Cursor::bind(const std::string &par,double &val,short *isNull) {		map<string,OCIBind *>::const_iterator ci=binds.find(par);	if(ci==binds.end()) {		binds[par]=0;	}  //reuse handler ... 	CHECKERR(errhp,OCIBindByName(stmthp,&(binds[par]),errhp,(CONST text *)par.c_str(),(sb4)strlen(par.c_str()),								 (dvoid *)&val,(sb4)sizeof(double),SQLT_FLT,(dvoid *)isNull,(ub2 *)0,								 (ub2 *)0,(ub4)0,(ub4 *)0,OCI_DEFAULT));	DEBUG(DLEV_DEBUG,"Bind done.param=%s,val=%f\n",par.c_str(),val);}void OCICPP::Cursor::bind(const std::string &par,RowID &rowid,short *isNull) {	map<string,OCIBind *>::const_iterator ci=binds.find(par);	if(ci==binds.end()) {		binds[par]=0;	}  //reuse handler ... 	OraRowID *rid=rowid.getRowID();	CHECKERR(errhp,OCIBindByName(stmthp,&(binds[par]),errhp,(CONST text *)par.c_str(),(sb4)strlen(par.c_str()),								 &(rid->rowid[curRow]),-1,SQLT_RDD,(dvoid *)isNull,(ub2 *)0,								 (ub2 *)0,(ub4)0,(ub4 *)0,OCI_DEFAULT));	DEBUG(DLEV_DEBUG,"Bind done.param=%s,val=ROWID\n",par.c_str());}void OCICPP::Cursor::bind(const std::string &par,Cursor &cur,short *isNull) {	map<string,OCIBind *>::const_iterator ci=binds.find(par);	if(ci==binds.end()) {		binds[par]=0;	}  //reuse handler ... 	cur.init(envhp,svchp,errhp,1,REFCURSOR);	CHECKERR(errhp,OCIBindByName(stmthp,&(binds[par]),errhp,(CONST text *)par.c_str(),(sb4)strlen(par.c_str()),								 (dvoid *)&(cur.stmthp),(sb4)0,SQLT_RSET,(dvoid *)isNull,(ub2 *)0,								 (ub2 *)0,(ub4)0,(ub4 *)0,OCI_DEFAULT));	DEBUG(DLEV_DEBUG,"Bind done.param=%s,val=Cursor\n",par.c_str());}void OCICPP::Cursor::bind(const std::string &par,Lob &lob,short *isNull) {	map<string,OCIBind *>::const_iterator ci=binds.find(par);	if(ci==binds.end()) {		binds[par]=0;	}  //reuse handler ... 	lob.init(envhp,svchp,errhp);	CHECKERR(errhp,OCIBindByName(stmthp,&(binds[par]),errhp,(CONST text *)par.c_str(),(sb4)strlen(par.c_str()),								 (dvoid *)&(lob.lob),(sb4)0,SQLT_BLOB,(dvoid *)isNull,(ub2 *)0,								 (ub2 *)0,(ub4)0,(ub4 *)0,OCI_DEFAULT));	DEBUG(DLEV_DEBUG,"Bind done.param=%s,val=Cursor\n",par.c_str());}	/* --------------------------------------*//*!  Fetch the content of the cursor's next row(s) from the database server  \return 0 if no new row is available */bool OCICPP::Cursor::fetch() {	unsigned tmp_fetched;	canFetch=1;	if(haveResultSet) {		curRow++;		if(curRow==fetched && fetched<prefetchRows) {			canFetch=0;		} else if(curRow==fetched || !fetched) {			status=OCIStmtFetch(stmthp,errhp,(ub4) prefetchRows,OCI_FETCH_NEXT,OCI_DEFAULT); 			tmp_fetched=fetched_all;			CHECKERR(errhp,OCIAttrGet(stmthp,OCI_HTYPE_STMT,&fetched_all,0,OCI_ATTR_ROW_COUNT,errhp));			fetched=fetched_all-tmp_fetched;			DEBUG(DLEV_DEBUG,"fetched=%d\n",fetched);			if(!fetched) {				canFetch=0;				DEBUG(DLEV_DEBUG,"No more rows\n");			} else {				canFetch=1;				curRow=0;			} 		} 	}	return (canFetch==1)?true:false;}/* 	get<Type> functions *//*! \fn int OCICPP::Cursor::getInt(const std::string &col,bool *isNull,const int *null_value) const  Return an integer value from the column named \a col . Unless pointing to 0,  \a *isNull is set to \c TRUE if the retreived value is NULL in the sence of  the database server. A client-specific value to be returned may be supplied  by having \a null_value point to this value.  \sa void getInt(int,int &,bool *,const int *) const,      int getInt(int,bool *,const int *) const,      void getInt(const std::string &,int &,bool *,const int *) const *//*! \fn int OCICPP::Cursor::getInt(int col,bool *isNull, const int *null_value) const  Return an integer value from the column indexed by \a col . Unless pointing  to 0, \a *isNull is set to \c TRUE if the retreived value is NULL in the  sence of the database server. A client-specific value to be returned may be  supplied by having \a null_value point to this value.  \sa void getInt(int,int &,bool *,const int *) const,      void getInt(const std::string &,int &,bool *,const int *) const,      int getInt(const std::string &,bool *, const int *) const *//*! \fn double OCICPP::Cursor::getDouble(const std::string &col,bool *isNull=0,const double *null_value=0)const  Return a double value from the column named \a col . Unless pointing  to 0, \a *isNull set to \c TRUE if a NULL-value is retreived in this way. The  value returned to the application may be specified by having \a null_value  pointing to it.  \sa void getDouble(int,double &,bool *,const double *) const,      double getDouble(int,bool *,const double *) const,      void getDouble(const std::string &,double &,bool *,const double *) const *//*! \fn double OCICPP::Cursor::getDouble(int col,bool *isNull, const double *null_value) const  Return a double value from the column indexed by \a col . Unless pointing  to 0, \a *isNull set to \c TRUE if a NULL-value is retreived in this way. The  value returned to the application may be specified by having \a null_value  pointing to it.  \sa void getDouble(int,double &,bool *,const double *) const,      void getDouble(const std::string &,double &,bool *,const double *) const,      double getDouble(const std::string &,bool *, const double *) const *//*! Retrieve content from column number \a col into the string \a str. If  \a isNull is not pointing to 0, this boolean reflects, if the cell's content  was NULL or not.  \sa void getStr(const std::string &,std::string &,bool *) const,      std::string getStr(const std::string &,bool *) const,      std::string getStr(int,bool *) const*/void OCICPP::Cursor::getStr(int col,std::string &str,bool *isNull) const {	if(!canFetch || col<0 || col>=nCols) throw OraError(CELL_NOT_EXISTS);	if(row[col]->isNull(curRow)) {		str.assign(nulltext);		if (isNull) *isNull = true;		return;	}	row[col]->getStr(str,curRow);	if (isNull) *isNull = false;}/*!  Retrieve a string value \a val from the column named \a colName out of the  current cursor position. If \a isNull is not pointing to 0, it is set  according to the returned value.   \sa void getStr(int,std::string &,bool *) const,      string getStr(const std::string &,bool *) const,      string getStr(int,bool *) const */void OCICPP::Cursor::getStr(const std::string &colName,std::string &val,bool *isNull) const {	map<string,int>::const_iterator iter=cols_map.find(colName);	if(iter!=cols_map.end()) {		getStr(iter->second,val,isNull);	} else {		std::cerr << " Cell is '" << colName << "'\n";		throw OraError(CELL_NOT_EXISTS);	}}/*! \fn string OCICPP::Cursor::getStr(int col,bool *isNull) const  Convenience function to retreive a string value from the cursor's current  position put of column \a col . If \a isNull is not pointing to 0, \a *isNull  is set to \c TRUE if the value retreived in this way was NULL in the database  \sa void getStr(const string &,string &,bool *) const,      void getStr(int,string &,bool *) const,      string getStr(const string &,bool *) const*//*! \fn string OCICPP::Cursor::getStr(const string &col,bool *isNull=0)const  Convenience function to retreive a string value from the cursor's current  position put of column named \a colName . If \a isNull is not pointing to 0,  \a *isNull is set to \c TRUE if the value retreived in this way was NULL in  the database  \sa void getStr(const string &,string &,bool *) const,      void getStr(int,string &,bool *) const,      string getStr(int,bool *) const *//*!  Read an integer value \a val from the column indexed by \a col . Unless  pointing to 0, \a *isNull is set to \c TRUE if the retreived value is NULL in  the sence of the database server. A client-specific value to be returned as   \a val may be supplied by having \a null_value point to this value.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -