• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Codejie's C++ Space

            Using C++

            OCI : do NOT debug on TWO different windows

                這兩天在使用Oracle,好久沒用了,生疏了很多。。。
                開始使用occi訪問,可以是代碼很精簡,因為occi封裝的還是很好的,使用起來跟mysql++很類似,也不知道他們誰參考誰的,反正用起來就是很簡單。
                聯(lián)調(diào)起來卻碰到了個大麻煩,本來說好是Linux平臺的,等調(diào)試時卻要換到Windows上,問題來了,occi11跟VC9似乎不合拍,Environment初始就出錯,折騰了很久,最終只有放棄了。測試下oci,嗯,可以用。。。
                于是,晚上一狠心,自己封裝oci,模仿occi做個ocipp來,好用了。。。

                這里說個調(diào)試過程中一件丟臉的事情--使用ocipp訪問同時,打開SQLPlus窗口,進(jìn)行對比測試,select語句很好用,但到update/delete語句時,程序卡死在execute調(diào)用中,想了很久,也嘗試了很久,到了凌晨1點(diǎn)半,一直卡死,人近瘋狂,突然想起,SQLPlus窗口下的語句默認(rèn)需要自己輸入commit語句提交的,而ocipp用的是Auto-commit方式,兩者應(yīng)該有沖突的。于是在SQLPlus輸入個commit,一切pass。。。
                所以,記得,調(diào)試oci接口時,不要開兩個窗口,會死人的。。。


                下面是ocipp代碼,僅供看熱鬧,不推薦使用,因為除了有危險外,也很有限制,比如ocipp僅支持string類型的define和bind,因為,我的代碼僅需要這一種類型。。。

            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(code)
            , _msg(msg)
            {
                getError(code);
            }


            Exception::Exception(
            int code, OCIError* err, const std::string &msg)
            : _code(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, NULL, NULL, 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, NULL, 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, NULL, 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, OCI_ATTR_STMT_TYPE, _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;
            }



            posted on 2011-07-08 11:23 codejie 閱讀(2103) 評論(2)  編輯 收藏 引用 所屬分類: C++輪子精神

            評論

            # re: OCI : do NOT debug on TWO different windows 2011-07-10 15:02 pansunyou

            我也封裝過類似的東西,DB2的CLI庫,也就自己爽,別人都不敢用。  回復(fù)  更多評論   

            # re: OCI : do NOT debug on TWO different windows 2011-07-11 14:38 codejie

            @pansunyou
            是的,很爽。。。  回復(fù)  更多評論   

            公告

            Using C++

            導(dǎo)航

            統(tǒng)計

            留言簿(73)

            隨筆分類(513)

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            欧美日韩精品久久久免费观看| 91精品无码久久久久久五月天| 久久精品一区二区三区不卡| 久久久久四虎国产精品| 亚洲国产成人久久笫一页| 精品久久久久久无码中文字幕 | 精品久久久久久国产| 亚洲人成网站999久久久综合| 国产精品一区二区久久国产| 久久久久久亚洲精品成人| 精品乱码久久久久久久| 日韩精品久久久久久久电影| 亚洲精品美女久久久久99小说| 久久精品国产亚洲欧美| 狠狠色丁香婷婷综合久久来来去| 色综合久久无码五十路人妻| 久久久久亚洲精品无码蜜桃| 性高湖久久久久久久久AAAAA| 国产激情久久久久影院老熟女| 欧美久久一级内射wwwwww.| 久久青草国产手机看片福利盒子| 久久久无码人妻精品无码| 一本一本久久aa综合精品| 久久国产精品99精品国产987| 精品国产乱码久久久久软件| 久久男人Av资源网站无码软件| 久久综合久久美利坚合众国| 久久久久一级精品亚洲国产成人综合AV区 | 人妻久久久一区二区三区| 亚洲午夜久久影院| 99久久人妻无码精品系列蜜桃 | 国内精品伊人久久久久777| 性做久久久久久久久| 欧美久久久久久午夜精品| 久久久久久A亚洲欧洲AV冫 | 久久国产亚洲高清观看| 亚洲AV无码久久精品狠狠爱浪潮 | 2021国内久久精品| 久久伊人精品一区二区三区| 久久人人爽人人爽人人片AV麻烦| 久久亚洲AV无码精品色午夜 |