时间: 2021-07-31 作者:daque
对于入门者,运用ado考察数据库的功夫,波及到百般数据典型变换,大概有少许难度,我试图封装了ado考察数据库,使其更简单的用现有的vc的数据典型,越发简单的运用ado操纵数据库。底下辨别供给两个封装ado数据库考察的类,一个是数据库的贯穿类,一个是数据库字段考察的类。 在贯穿类中,大师不妨看到,贯穿类中并没有recordset的分子变量,由于如许的,在所有数据库运用步调中,数据库的贯穿普遍一个就够了,而同声翻开的reocordset则大概不止一个,以是,即使两个在同一个类里,那么,即使要同声翻开两个记载集,须要创造类的两个范例,即是须要同声翻开两个数据库贯穿,即使对于贯穿的是同一个数据库,同声翻开两个贯穿的话,表示着资源的不需要的滥用。 数据库字段考察类,简化了,获得数据库字段实质的操纵,制止了数据典型变换的烦恼。 两个类都对缺点处置举行了较多的商量,在考察数据库中,即使没有缺点处置,其坏处是不言而喻的。#ifndef _bbadoconnect_h#define _bbadoconnect_h//// ado考察数据库类// 软硬件情况:须要msado15.dll// 作家:邓振波// 2001.4.20// email:bozi@china.com// 证明:封装了ado运用的操纵因变量和ado考察数据库缺点处置// 使在vc上简单的运用ado考察数据库// 囊括:ado贯穿数据库、翻开记载集、实行sql、以及// 工作处置、ado记载集实质变换成c++的常用数据典型(cstring、char,long,float等)//// 运用:1。设置一个cbbadoconnection范例:cbbadoconnection m_adoconn;// 2。创造贯穿:m_adoconn.open(strconnstring);// 即使须要无前提从新贯穿的不妨,参数brepen设成treu// 3。翻开记载集://// _recordsetptr* prsthis=null;// prsthis=new _recordsetptr;// cstring strsql;// strsql="select * from table_name";// // 即使记载集翻开波折// if(!(m_adoconn.openrecordset(strsql,prsthis)))// return false;// 4。创造记载集值东西// 提防须要用参数结构// cbbrstvalues rsv(m_adoconn,prsthis);// // 5。赢得的字段的值// rsv.getvaluelong(&m_ndeptid,1l);//赢得第一个字段的值// rsv.getvaluestr(m_strname,"id");//赢得第一个字段名为id的值// 其它的同理.即使须要赢得sql server中ntext典型的字段值请用// getvaltext(cstring &strtext, cstring &strfieldname)因变量// 6。记载集的记载挪动 (*prsthis)->movenext()等一致因变量// 7。记载集不必功夫须要开释其资源// 1)封闭记载集// 2)简略记载集南针// e.g. (*prsthis)->close();// delete prsthis;// prsthis=null;// 要不会形成外存揭发// // 注:// 1。步调必需要初始化com情况,请在运用类中介入afxoleinit因变量初始化情况,要不ado的挪用将波折// 2。即使须要挪用保存进程sql语句改为“exec ” + 保存进程名即可,与实行sql同样//// copyright seesi,2001//// 证明:你不妨随意在的步调中大肆运用、窜改本代码,但请你不要简略文献头的局部证明。即使须要连载,请证明根源。// msado15.dll必需放在本文献地方目次,大概本人指定底下的msado15.dll全路途// #if !defined(__afxado_h)#import "msado15.dll" no_namespace rename ("eof", "adoeof") \ rename ("locktypeenum", "adolocktypeenum") \ rename ("datatypeenum", "adodatatypeenum") \ rename ("fieldattributeenum", "adofieldattributeenum") \ rename ("editmodeenum", "adoeditmodeenum") \ rename ("recordstatusenum", "adorecordstatusenum") \ rename ("parameterdirectionenum", "adoparameterdirectionenum")#endif // !defined(__afxado_h)class cbbadoconnection {public: cbbadoconnection(); virtual ~cbbadoconnection();public: int setconntimeout(long ltimeout); // 树立贯穿超时 int setcommtimeout(long ltimeout); // 树立吩咐实行超时 bool isconnectclose(); // 确定贯穿能否仍旧翻开 int executesql(lpcstr szsql); // 大略实行sql语句,不归来记载集 // 翻开数据库记载集 // 参数: // strsql 记载集的sql语句 // rs 归来的记载集_recordsetptr东西 // sconnstring 数据库的贯穿字符串 // 即使运用数据库贯穿仍旧翻开,参数没用 // 即使数据库的贯穿没有翻开,当赋予一个贯穿字符串,将先翻开数据库贯穿 bool openrecordset(cstring strsql, _recordsetptr *rs,cstring sconnstring="");//翻开数据库记载集 bool openrecordset(const char *ssql,_recordsetptr* rs,char* sconnstring=null); // 翻开数据库贯穿 // 参数: // strconnstring 贯穿字符串 // sconnstring 贯穿字符串 // breopen 能否从新翻开,即使为false,, // 将先确定数据库能否翻开即使没有翻开则翻开, // 即使仍旧翻开,将不实行任何操纵 // 即使为true,则无前提从新翻开。 bool openconnection(cstring strconnstring ,bool breopen=false); bool openconnection(char* sconnstring,bool breopen=false); void closeconnect();// 封闭数据库贯穿 bool executetrans(cstringarray arrstrsql); // 工作处置,不归来任何记载集,参数为工作sql数组 _connectionptr* getconnection(); // 获得_connectionptr南针 cstring getconnstring(); // 获得贯穿字符串 private: enum errorfrom { errformopenconnsction, errfromopenrecordset, errformcloseconnection, errformtanslation }; _connectionptr* m_pconn; char m_szconnstring[512]; ///protected: void reporterror(int nerrorfrom);};class cbbrstvalues { public: // 三种结构类的本领 // 即使无参数结构,请结构后挪用initconnectandrst本领 // 其余的两种结构则不需挪用initconnectandrst本领 cbbrstvalues(); cbbrstvalues(_connectionptr* pconn,_recordsetptr* prs); cbbrstvalues(cbbadoconnection* pbbadoconn,_recordsetptr* prs); virtual ~cbbrstvalues();public: // 初始化贯穿队象和记载集东西 void initconnectandrst(_connectionptr* pconn,_recordsetptr* prs); void initconnectandrst(cbbadoconnection* pbbadoconn, _recordsetptr * rs); // getvaltext因变量 // 获得数据库ntext字段的值 // 参数: // strtext 用来接受归来值(字段值) // strfieldname 字段名,该字段数据典型必需是ntext典型 bool getvaltext(cstring& strtext,cstring& strfieldname); //获得数据库ntext字段的值 // getvaluestr因变量 // 获得数字型,日子型和字符型字段值因变量 // 参数: // cval 用来接受归来值(字段值)的字符串南针,诉求要开拓充满的外存单位 // 大概充满包含字段实质的字符数组。 // vindex 数据库字段的名字大概索引,变体型,普遍不径直用这个参数, // 该当用同情势的多态因变量的参数挪用 // 数据库字段的数据典型不妨是数字型,日子型和字符型 // nfieldlen 须要归来的数据的字符串的长度,即使为-1,则归来所有字段值 // lpszfieldname 字段名,数据库字段的数据典型不妨是数字型,日子型和字符型 // nfieldindex 在sql语句中字段的索引序号数据库字段的数据典型不妨是数字型,日子型和字符型 // getvaluelong因变量 // 获得数字型,日子型和字符型字段值因变量 // 参数: // lval 用来接受归来值(字段值) // vindex 数据库字段的名字大概索引,变体型,普遍不径直用这个参数, // 该当用同情势的多态因变量的参数挪用 // 数据库字段的数据典型诉求是数字型(int,long) // lpszfieldname 字段名,数据库字段的数据典型不妨是数字型,日子型和字符型 // nfieldindex 在sql语句中字段的索引序号数据库字段的数据典型不妨是数字型,日子型和字符型 // getvalueflaot因变量 // 获得数字型,日子型和字符型字段值因变量 // 参数: // fval 用来接受归来值(字段值) // vindex 数据库字段的名字大概索引,变体型,普遍不径直用这个参数, // 该当用同情势的多态因变量的参数挪用 // 数据库字段的数据典型诉求是字型(int,long,float,钱币型等) // lpszfieldname 字段名,数据库字段的数据典型不妨是数字型,日子型和字符型 // nfieldindex 在sql语句中字段的索引序号数据库字段的数据典型不妨是数字型,日子型和字符型 bool getvaluestr(char* cval,_variant_t &vindex,int nfieldlen=-1); bool getvaluelong(long* lval,_variant_t &vindex); bool getvaluefloat(float* fval,_variant_t &vindex); bool getvaluestr(char* cval,long lindex,int nfieldlen=-1); bool getvaluelong(long* lval,long lindex); bool getvaluefloat(float* fval,long lindex); bool getvaluestr(char* cval,cstring strindex,int nfieldlen=-1); getvaluelong(long *lval, lpcstr lpszindex); bool getvaluefloat(float* fval,cstring strindex); bool getvaluestr(cstring& str,lpcstr lpszfieldname,int nfieldlen=-1); bool getvaluestr(cstring& str,uint nfieldindex,int nfieldlen=-1); bool getvaluestr(cstring& str,_variant_t &vindex,int nfieldlen=-1); // 确定值能否灵验,能否为null bool verifyvtdata(_variant_t& value); bool verifyvtdata(char* pdata); protected: _recordsetptr* m_prsthis; _connectionptr* m_pconn; void reporterror();};#endif // _bbadoconnect_h////cpp文献//////////////////////////////////////////////////////////////////////// construction/destruction//////////////////////////////////////////////////////////////////////cbbadoconnection::cbbadoconnection(){ m_pconn=null;}_connectionptr* cbbadoconnection::getconnection(){ return m_pconn;}cstring cbbadoconnection::getconnstring(){ return m_szconnstring;}cbbadoconnection::~cbbadoconnection(){ // 关比贯穿 closeconnect();}bool cbbadoconnection::openconnection(char *sconnstring,bool breopen /*=false*/){ // 不需从新翻开 if(!breopen) { if(m_pconn !=null && ((*m_pconn)->state!=adstateclosed)) return true; } verify(sconnstring); strcpy(m_szconnstring,sconnstring); try { m_pconn =new _connectionptr; m_pconn->createinstance(__uuidof(connection)); if(m_pconn==null) return false; hresult hr=(*m_pconn)->open((char*)sconnstring,"","",-1); if(failed(hr)) return false; return true; } catch(_com_error) { reporterror(errformopenconnsction); return false; } catch(...) { #ifdef _debug // 调节和测试时表露相映的缺点消息 messagebox(null,"数据库贯穿未处置的特殊!","贯穿波折",mb_ok|mb_iconinformation); #else messagebox(null,"贯穿数据波折,请查看搜集和数据库树立能否精确","贯穿波折",mb_ok|mb_iconinformation); #endif return false; } setconntimeout(5);}bool cbbadoconnection::openrecordset(const char *ssql, _recordsetptr *rs, char *sconnstring){ // rs=new _recordsetptr; verify(ssql); try { if((m_pconn==null)||((*m_pconn)->state==adstateclosed)) { int n=(*m_pconn)->state; if(sconnstring!=null) { if(!openconnection(sconnstring)) return false; } // 试验贯穿数据库 else { // // if(!openconnection(m_szconnstring)) // return false; // messagebox(null,"数据库贯穿仍旧割断,请从新贯穿!","贯穿题目",mb_ok|mb_iconinformation); } return false; } // rs=new _recordsetptr; hresult hr; hr=rs->createinstance(__uuidof(recordset)); if(failed(hr)) { return false;// 创造范例波折 } hr=(*rs)->open(ssql,m_pconn->getinterfaceptr(), adopenstatic, adlockbatchoptimistic, -1); if(failed(hr)) { return false;// 翻开贯穿波折 } return true;// 胜利归来 } catch(_com_error) { // afxmessagebox(ce->description()); reporterror(errfromopenrecordset); return false; } catch(...) { messagebox(null,"数据库记载翻开波折!","记载波折",mb_ok|mb_iconinformation); return false; } return true;}void cbbadoconnection::closeconnect(){ try { if(m_pconn!=null) { if((*m_pconn)->state!=adstateclosed) (*m_pconn)->close(); delete m_pconn; m_pconn=null; } } catch(_com_error) { reporterror(errformcloseconnection); } catch(...) { afxmessagebox("封闭数据库贯穿未知缺点!"); }}bool cbbadoconnection::openconnection(cstring strconnstring, bool breopen){ char c[512]; strcpy(c,strconnstring.getbuffer(0)); strconnstring.releasebuffer(); return openconnection(c,breopen);}bool cbbadoconnection::openrecordset(cstring strsql, _recordsetptr *rs, cstring sconnstring){ char c[1024]; strcpy(c,strsql.getbuffer(0)); strsql.releasebuffer(); return openrecordset(c,rs,(char*)(lpctstr)sconnstring); }bool cbbadoconnection::executetrans(cstringarray arrstrsql) // 发端工作处置,不归来任何记载集,参数为工作sql数组{ (*m_pconn)->begintrans(); try { _recordsetptr* prsthis; for(int i=0;i<arrstrsql.getsize();i++) { prsthis=new _recordsetptr; openrecordset(arrstrsql.elementat(i),prsthis); delete prsthis; } prsthis=null; (*m_pconn)->committrans(); return true; } catch(_com_error) { (*m_pconn)->rollbacktrans(); reporterror(errformtanslation); return false; } }// 实行sql操纵,不归来记载集int cbbadoconnection::executesql(lpcstr szsql){ // variant veffect; try { (*m_pconn)->execute(szsql,null,adcmdtext|adexecutenorecords); return true; } catch(_com_error) { reporterror(errformtanslation); return false; } // return veffect.lval;}// 归来能否处在贯穿状况bool cbbadoconnection::isconnectclose(){ return (m_pconn==null)||((*m_pconn)->state==adstateclosed);}// 树立贯穿超时int cbbadoconnection::setconntimeout(long ltimeout){ return (*m_pconn)->put_connectiontimeout(ltimeout);}int cbbadoconnection::setcommtimeout(long ltimeout){ return (*m_pconn)->put_commandtimeout(ltimeout);}// 汇报缺点void cbbadoconnection::reporterror(int nerrorfrom){ switch(nerrorfrom) { case errformopenconnsction: #ifdef _debug // 调节和测试试时表露相映的缺点消息 try { for(long l=0;l<(*m_pconn)->errors->count;l++) { errorptr perr; perr=(*m_pconn)->errors->getitem(l); cstring str; str=(char*)perr->description; messagebox(null,str,"贯穿波折",mb_ok|mb_iconinformation); } } catch(...) { messagebox(null,"数据库贯穿未知缺点,没辙捕获简直缺点消息!","缺点",mb_iconinformation); } #else messagebox(null,"贯穿数据波折,请查看搜集和数据库树立能否精确","贯穿波折",mb_ok|mb_iconinformation); #endif break; case errfromopenrecordset: #ifdef _debug try { for(long i=0;i<(*m_pconn)->errors->count;i++) { errorptr perr; perr=(*m_pconn)->errors->getitem(i); afxmessagebox(perr->description); } } catch(...) { messagebox(null,"数据库贯穿未知缺点,没辙捕获简直缺点消息!","缺点",mb_iconinformation); } #else messagebox(null,"翻开数据库波折,请查看搜集,并试验从新贯穿数据库!","记载波折",mb_ok|mb_iconinformation); #endif break; case errformcloseconnection: #ifdef _debug // 调节和测试时表露相映的缺点消息 try { for(long l=0;l<(*m_pconn)->errors->count;l++) { errorptr perr; perr=(*m_pconn)->errors->getitem(l); cstring str; str=(char*)perr->description; messagebox(null,str,"贯穿波折",mb_ok|mb_iconinformation); } } catch(...) { messagebox(null,"数据库贯穿未知缺点,没辙捕获简直缺点消息!","缺点",mb_iconinformation); } #else ;// messagebox(null,"封闭数据库贯穿特殊","封闭特殊",mb_ok|mb_iconinformation); #endif break; case errformtanslation: #if def _debug try { for(long i=0;i<(*m_pconn)->errors->count;i++) { errorptr perr; perr=(*m_pconn)->errors->getitem(i); afxmessagebox(perr->description); } } catch(...) { messagebox(null,"数据库贯穿未知缺点,没辙捕获简直缺点消息!","缺点",mb_iconinformation); } #else messagebox(null,"数据库实行工作波折,请查看数据库。","工作波折",mb_ok|mb_iconinformation); #endif break; default: break; }}/////////////// crecordsetvaluscbbrstvalues::cbbrstvalues(){ ;}cbbrstvalues::cbbrstvalues(_connectionptr* pconn,_recordsetptr* prs){ assert(pconn); assert(prs); m_prsthis=prs; m_pconn=pconn;}cbbrstvalues::cbbrstvalues(cbbadoconnection* pbbadoconn,_recordsetptr* prs){ cbbrstvalues(pbbadoconn->getconnection(),prs);}cbbrstvalues::~cbbrstvalues(){ ;}void cbbrstvalues::initconnectandrst(_connectionptr *pconn, _recordsetptr *prs){ assert(pconn); assert(prs); m_prsthis=prs; m_pconn=pconn;}void cbbrstvalues::initconnectandrst(cbbadoconnection *pbbadoconn, _recordsetptr *prs){ initconnectandrst(pbbadoconn->getconnection(),prs);}bool cbbrstvalues::getvaluelong(long *lval, _variant_t &vindex){ _variant_t value; try{ if((*m_prsthis)==null||(*m_prsthis)->state==adstateclosed) {#ifdef _debug afxmessagebox("记载集未翻开!");#else messagebox(null,"没辙读取数据库材料,大概数据库贯穿仍旧割断,请从新贯穿、而后重试。","贯穿题目",mb_iconinformation);#endif return false; } if((*m_prsthis)->adoeof) { lval=0; return false; } value=(*m_prsthis)->getcollect(vindex); } catch(_com_error) { reporterror(); return false; } catch(...) { afxmessagebox("数据库字段考察未知缺点!请查看数据库能否变换。",mb_iconinformation); return false; } if(verifyvtdata(value)) { *lval = long(value); } else { *lval=0; } return true;}bool cbbrstvalues::getvaluestr(char *cval, _variant_t &vindex, int nfieldlen){ char * c=null; _variant_t value; date dt; cstring str; coledatetime da; // 查看是数组 // verify(sizeof(cval)<1); memset(cval,0,sizeof(cval)); try { if((*m_prsthis)==null||(*m_prsthis)->state==adstateclosed) {#ifdef _debug afxmessagebox("记载集未翻开!");#else messagebox(null,"没辙读取数据库材料,大概数据库贯穿仍旧割断,请从新贯穿、而后重试。","贯穿题目",mb_iconinformation);#endif return false; } if((*m_prsthis)->adoeof) { cval[0]='\0'; return false; } value = (*m_prsthis)->getcollect(vindex); } catch(_com_error) { reporterror(); // afxmessagebox("数据库字段考察缺点!"); return false; } catch(...) { afxmessagebox("数据库字段考察未知缺点!请查看数据库能否变换。",mb_iconinformation); return false; } if(verifyvtdata(value)) { switch(value.vt) { case vt_bstr: c = (char *)_com_util::convertbstrtostring( v_bstr(&value) ); if(verifyvtdata(c)) { if(nfieldlen<=0) { strcpy(cval,(char*)c); } else { strncpy(cval, (char*)c, nfieldlen); } } delete c; c=null; break; case vt_i4: case vt_decimal: case vt_ui4: case vt_i8: case vt_ui8: case vt_int: case vt_uint: long lval; lval = long(value); ltoa(lval,cval,10); break; case vt_date: dt=value.date; da=coledatetime(dt); // str=da.format("%y-%m-%d %h:%m:%s"); str=da.format("%y-%m-%d "); c=new char[64]; memset(c,0,sizeof(char)*64); strcpy(c,str.getbuffer(0)); str.releasebuffer(); if(verifyvtdata(c)) { if(nfieldlen<=0) { strcpy(cval,(char*)c); } else { strncpy(cval, (char*)c, nfieldlen); cval[nfieldlen]='\0'; } } delete c; c=null; break; default:#ifdef _debug afxmessagebox("未处置的字段数据典型,请处置!");#else break;#endif break; } } else { cval[0]='\0'; } return true;}bool cbbrstvalues::getvaluelong(long *lval, long lindex){ _variant_t vindex(lindex); return getvaluelong(lval,vindex);}bool cbbrstvalues::getvaluelong(long *lval, lpcstr lpszindex){ _variant_t vindex(lpszindex); return getvaluelong(lval,vindex);}bool cbbrstvalues::verifyvtdata(char *pdata){ if(pdata == null) { return false; } return true;}bool cbbrstvalues::verifyvtdata(_variant_t &value){ if(value.vt == vt_null) { return false; } return true;}bool cbbrstvalues::getvaluestr(cstring& str,lpcstr lpszfieldname,int nfieldlen/*=-1*/){ _variant_t vindex(lpszfieldname); return getvaluestr(str,vindex,nfieldlen);}bool cbbrstvalues::getvaluestr(cstring& str,uint nfieldindex,int nfieldlen/*=-1*/){ _variant_t vindex((long)nfieldindex); return getvaluestr(str,vindex,nfieldlen);}bool cbbrstvalues::getvaluestr(cstring& str,_variant_t &vindex,int nfieldlen/*=-1*/){ tchar buffer[1024]; if(nfieldlen > 1023) nfieldlen = 1023; bool bresult=getvaluestr((char*)buffer,vindex,nfieldlen); str.format(buffer); str.trimright(); return bresult;}bool cbbrstvalues::getvaluefloat(float* fval,_variant_t &vindex){ _variant_t value; try { if((*m_prsthis)==null||(*m_prsthis)->state==adstateclosed) { #ifdef _debug afxmessagebox("记载集未翻开!");#else messagebox(null,"没辙读取数据库材料,大概数据库贯穿仍旧割断,请从新贯穿、而后重试。","贯穿题目",mb_iconinformation);#endif return false; } if((*m_prsthis)->adoeof) { fval=0; return false; } value=(*m_prsthis)->getcollect(vindex); } catch(_com_error) { reporterror(); return false; } catch(...) { afxmessagebox("数据库字段考察未知缺点!请查看贯穿数据库构造能否仍旧变动。",mb_iconinformation); return false; } if(verifyvtdata(value)) { *fval = float(value); } else { *fval = 0; } return true;}bool cbbrstvalues::getvaluefloat(float* fval,long lindex){ _variant_t vindex(lindex); return getvaluefloat(fval,vindex);}bool cbbrstvalues::getvaluefloat(float* fval,cstring strindex){ _variant_t vindex(strindex); return getvaluefloat(fval,vindex);}bool cbbrstvalues::getvaluestr(char *cval,long lindex,int nfieldlen){ _variant_t vindex; vindex=_variant_t(lindex); return getvaluestr(cval,vindex); }bool cbbrstvalues::getvaluestr(char *cval,cstring strindex,int nfieldlen){ _variant_t vindex; vindex=_variant_t(strindex); return getvaluestr(cval,vindex); }void cbbrstvalues::reporterror(){#ifdef _debug try { for(long l=0;l<(*m_pconn)->errors->count;l++) { errorptr perr; perr=(*m_pconn)->errors->getitem(l); afxmessagebox(perr->description); } } catch(...) { afxmessagebox("字段缺点东西考察缺点,请查看抄写能否精确。"); }#else messagebox(null,"字段考察爆发缺点,请确认数据库构造没有变换。","字段考察",mb_iconinformation);#endif // afxmessagebox("数据库字段考察缺点!"); }bool cbbrstvalues::getvaltext(cstring &strtext, cstring &strfieldname){ _bstr_t varchunk; _bstr_t varnotes; long lngtotalsize, lngoffset = 0, lngchunksize = 100; _variant_t vfieldname = _variant_t(strfieldname); lngtotalsize = (*m_prsthis)->fields->item[vfieldname]->actualsize/2; if (lngtotalsize <= 0) return false; try { while (lngoffset < lngtotalsize) { varchunk = (*m_prsthis)->fields->item[vfieldname]->getchunk(lngchunksize); varnotes = varnotes + varchunk; lngoffset = lngoffset + lngchunksize; } strtext=(char*)varnotes; } catch(_com_error) { reporterror(); return false; } catch(...) {#ifdef _debug afxmessagebox("获得text字段未知缺点");#endif return false; } return true;}// 上头代码,再有没有完备的场合,更完备的代码,在此后会公布,此刻我仍旧做出了一个dll,并而再有少许示例文献,须要dll和示例文献的,请与我接洽。email: bozi@china.com