?? tociquery.h
字號:
#ifndef _OCIQuery_h#define _OCIQuery_h#include <oci.h>#include <stdio.h>#include "exception.h"//#define __DEBUG__typedef signed int dword;const int PREFETCH_ROWS = 200; //預先提取n行數據到緩沖區,減少網絡流量const int MAX_STRING_VALUE_LENGTH = 255; //返回的字符串最大的列、返回過程參數長度const int MAX_LOB_BUFFER_LENGTH = 1024; //LOB數據緩沖區的最大空間const int MAX_ERRMSG_LENGTH = 1024; //錯誤信息的最大長度const int MAX_SQLSTMT_LENGTH = 1024; //出現錯誤的SQL語句長度//const int MAX_PARAMS_COUNT = 100; //參數最大數目const int MAX_PARAMS_COUNT = 150; //清單表結構大約100個字段 3.28修改const int MAX_ERR_CAT_LENGTH = 50; //錯誤分類長度const int LOB_FLUSH_BUFFER_SIZE = 400*1024; //LOB數據積累到此量時,寫入數據庫//error message definination:const char* const ERR_GENERAL = "General Error: %s"; //throw TOCIException("TOCIQuery(TOCIDatabase &db)", ERR_GENERAL, "Can not declare a TOCIQuery when the database is not connected");const char* const ERR_INDEX_OUT_OF_BOUND = "%s"; //throw TOCIException(fSqlStmt , ERR_INDEX_OUT_OF_BOUND, "field index out of bound when call Field(i)"); const char* const ERR_DB_INIT = "OCI: OCI handles init fail in TDatabase constructor: @line:%d";const char* const ERR_SET_LOGIN = "OCI: You can only set login infomation on disconnect status: line %d";const char* const ERR_CONNECT_NO_LOGIN_INFO = "No login information provided before Connect(), call SetLogin first, line:%d";const char* const ERR_NO_DATASET = "OCI: function:%s , Result Dataset is on Bof/Eof. field:%s"; //throw TOCIException(fParentQuery->fSqlStmt, ERR_NO_DATASET, "asBlobBuffer()", name);const char* const ERR_DATA_TYPE_CONVERT = "Data type convertion error: field:%s data type:%d can not be access by %s"; //throw TOCIException(fParentQuery->fSqlStmt, ERR_DATA_TYPE_CONVERT, name, type, "asLobBuffer()");const char* const ERR_NOMORE_MEMORY_BE_ALLOCATED = "no more memory can be allocate when :%s, source code:%d"; //throw TOCIException(fParentQuery->fSqlStmt, ERR_NOMORE_MEMORY_BE_ALLOCATED, "asBlobBuffer()", __LINE__);const char* const ERR_FILE_IO = "%s: can not open file:%s"; //throw TOCIException(fParentQuery->fSqlStmt, ERR_FILE_IO, "loadFromFile()", fileName);const char* const ERR_MEM_BUFFER_IO = "asBlobWriter() error: read from file to buffer, field:%s, file:%s, @line:%d"; //throw TOCIException(fParentQuery->fSqlStmt, ERR_MEM_BUFFER_IO, name, fileName, __LINE__);const char* const ERR_DATA_TYPE_NOT_SUPPORT = "field:%s, datatype:%d not yet supported"; //, pCurrField->name,innerDataType);const char* const ERR_PARAM_NOT_EXISTS = "param:%s does not exists."; //throw TOCIException(fSqlStmt, ERR_PARAM_NO_EXISTS, paramName, "check spelling error");const char* const ERR_FIELD_NOT_EXISTS = "field:%s does not exists.";const char* const ERR_INVALID_METHOD_CALL = "%s: invalid call method:%s";const char* const ERR_CAPABILITY_NOT_YET_SUPPORT = "capability not support yet:%s"; //例如參數個數超越范圍const char* const ERR_READ_PARAM_DATA = "read parameter value data type error, parameter name:%s, method:%s";//const define:const char* const NULL_STRING = "";const int NULL_NUMBER = 0;/* classes defined in this file: */class TOCIException;class TOCIDatabase;class TOCIQuery;class TOCIField;class TOCIParam;class TOCISession;class TOCIDirPath; //define in TOCIDirPath.hclass TOCIException : public TException{public: char *getErrMsg() const; char *getErrSrc() const; int getErrCode() const;public: TOCIException(sword errNumb, OCIError *err, char const *cat, char const *sql);//執行OCI函數發生的錯誤 TOCIException(const char *sql, const char* errFormat, ...); ~TOCIException();private: char errCategory[MAX_ERR_CAT_LENGTH+1]; //錯誤分類 text errMessage[MAX_ERRMSG_LENGTH+1]; //錯誤信息 char errSQL[MAX_SQLSTMT_LENGTH+1]; //發生錯誤的sql語句 int errNo; //錯誤號 int m_iErrCode;};class TOCIDatabase{friend class TOCIQuery;friend class TOCISession;friend class TOCIDirPath;public:public: TOCIDatabase(); ~TOCIDatabase(); void setLogin(char *user, char *password, char *tnsString) ; bool connect(); bool connect(char *usr, char *pwd, char *tns) ; void disconnect(); void commit(); void rollback(); OCISession *hUser; //OCISvcCtx *hSvc; //服務 OCISvcCtx *hDBSvc; //用于登錄鏈接服務器 private: char *usr, *pwd, *tns; //登錄名 bool fConnected; //在Connect中是否連接成功 sword fErrorNo; //錯誤號 void checkError() ; //用于判斷當前的語句是否正確執行,如果有錯誤則把錯誤信息放入errMsg; OCIError *hDBErr; OCIEnv *hEnv; OCIServer *hSvr;};class TOCIParam{friend class TOCIQuery;public: ~TOCIParam(); char *name; int asInteger(); //讀取返回參數值 double asFloat(); long asLong(); char *asString(); bool isNULL(); TOCIParam();private: ub2 dataType; int intValue; double dblValue; //存儲輸入和輸出的值(緩沖區) long longValue; //long數據緩沖區 char *stringValue; //字符串返回緩沖區 int * intArray; //INT數組 double * dblArray; //DOUBLE數組 long * longArray; //LONG數組 char ** stringArray; //STRING數組 int stringSize; //string數組中的string大小 bool fIsOutput; //是否是輸出參數.默認是輸入參數 sb2 indicator; //在返回值時候是否為空 OCIBind *hBind;};class TOCIField{friend class TOCIQuery;public: ~TOCIField(); char *name; //字段名稱 long size; //數據長度 long type; //數據類型 in(INT_TYPE,FLOAT_TYPE,DATE_TYPE,STRING_TYPE,ROWID_TYPE) int precision; //數值總長度 int scale; //數值中小數點個數 bool nullable; //字段定義時是否允許為空值--為了和其他的相一致 bool isNULL(); //在fetch過程中該列的數據是否為空 char *asString(); double asFloat(); int asInteger(); long asLong(); //Blob處理 void asBlobFile(const char *fileName); //讀取到file中 void loadFromFile(const char *fileName); //寫入到blob中 void loadFromBuffer(unsigned char *buf, unsigned int bufLength); //把LOB的內容用緩沖區內容替代 void asBlobBuffer(unsigned char* &buf, unsigned int *bufLength); //保存到緩沖區,緩沖區的大小自動創建,并返回緩沖區大小*bufLength. //日期處理 char *asDateTimeString(); //把日期型的列以HH:MM:DD HH24:MI格式讀取,使用asString()讀取的日期型數據類型為HH:MM:DD void asDateTime(int &year, int &month, int &day, int &hour, int &minute, int &second); //返回日期的各個部分 TOCIField();private: //日期處理 void asDateTimeInternal(int &year, int &month, int &day, int &hour, int &minute, int &second); //返回日期的各個部分,沒有作其他校驗,只是內部調用 TOCIQuery *fParentQuery; //指向該Field所屬于的Query //數據緩沖區,分別為字符串、整數、浮點數分配空間 ub1 fStrBuffer[MAX_STRING_VALUE_LENGTH]; //用于保存轉換為字符串后的值 ub1 *fDataBuf; //在分析字段時候獲得空間max(該列的最大長度,MAX_STRING_VALUE_LENGTH), 在Destructor中釋放 OCILobLocator *hBlob; //支持LOB sb2 *fDataIndicator; //在defineByPos中使用,用于在fetch時察看是否有字段值返回、字段值是否被截斷;valueIsNULL, isTruncated根據此值獲得結果 ub2 fReturnDataLen; //讀取數據時返回的真實長度 ub2 fInternalType; //Oracle內部數據類型 ub2 fRequestType; //在讀取數據時候的請求數據類型 OCIDefine *hDefine; //用于讀取列信息 int iBlobBufCnt; //支持LOB緩沖的長度};class TOCIQuery{friend class TOCIField;public: //主要功能 void close(); //關閉SQL語句,以準備接收下一個sql語句 void setSQL(const char *inSqlstmt); //設置Sqlstatement void open(int prefetchRows=PREFETCH_ROWS); //打開SQL SELECT語句返回結果集 bool next(); //移動到下一個記錄 bool execute(int iters=1); //執行非SELECT語句,沒有返回結果集 bool commit(); //事務提交 bool rollback(); //事務回滾 int rowsAffected() { return fTotalRowsFetched;}; //DELETE/UPDATE/INSERT語句修改的記錄數目 int getSQLCode() { return fErrorNo;}; //返回Oracle執行結果代碼 //與列信息相關 int fieldCount(); //總共有幾個列 TOCIField& field(int index) ; //返回第i個列信息 TOCIField& field(char const *fieldName) ; //根據列名(不分大小寫)返回列信息; 建議使用Field(int i)獲得更高的效率 //與參數信息相關 int paramCount(); TOCIParam& param(int index); //返回第i個列信息 TOCIParam& param(char *paramName); //根據列名(不分大小寫)返回列信息; 建議使用Field(int i)獲得更高的效率 //以下是設置參數值 void setParameter(const char *paramName, const char* paramValue, bool isOutput = false); void setParameter(const char *paramName, int paramValue, bool isOutput = false); void setParameter(const char *paramName, double paramValue, bool isOutput = false) ; void setParameter(const char *paramName, long paramValue, bool isOutput = false); void setParameterNULL(const char *paramName); /* 新增 long raw 處理 */ void setLongRawParameter(char *paramName, char* paramValue, bool isOutput = false); /* 新增 blob 處理 */ void setParameter(char *paramName, void* paramValue, int iLen,bool isOutput = false); //數組操作 void setParamArray(char const *paramName, char ** paramValue,int iStructSize,int iStrSize ,bool isOutput = false); void setParamArray(char const *paramName, int * paramValue,int iStructSize, bool isOutput = false); void setParamArray(char const *paramName, double * paramValue, int iStructSize,bool isOutput = false) ; void setParamArray(char const *paramName, long * paramValue, int iStructSize,bool isOutput = false); /* 新增blob處理 */ void setParamArray(char const *paramName, void ** paramValue,int iStructSize,int iStrSize, bool isOutput=false); //constructor & destructor TOCIQuery(TOCIDatabase *oradb); TOCIQuery(TOCIDatabase *oradb,TOCISession *session); ~TOCIQuery(); private: char *fSqlStmt; //保存open的Select語句,可以方便調試 ub2 fStmtType; //***ub2!!! 保存sqlstmt的類型:SELECT/UPDATE/DELETE/INSERT/CREATE/BEGIN/ALTER... bool fActivated; //是否已經處于打開狀態,在調用OCIStmtPrepare成功后為True unsigned fFetched; //0..prefetchRows unsigned fPrefetchRows; //1.. unsigned fCurrRow; //0..fetched */ unsigned fTotalRowsFetched; //rows fetched from the start int fFieldCount; //字段個數 TOCIDatabase *db; //此query屬于哪個Dabase,在Constructor中創建 TOCIField *fieldList; //在內部保存的所有字段信息 void getFieldsDef(); //獲得字段信息,并為字段分配取值的緩沖區 TOCIParam *paramByName(const char *paramName);//在內部使用,直接返回參數的指針 void checkError() ; //用于判斷當前的語句是否正確執行,如果有錯誤則把錯誤信息放入errMsg; int fParamCount; //參數個數 TOCIParam *paramList; //所有參數設置的信息 void getParamsDef(); //在setSQL時候獲得參數信息 int nTransTimes; //是否曾經執行過Execute()事務操作,以便與回滾. //OCITrans* hTrans; OCIStmt *hStmt; //用于分析sql語句的handle OCIError *hErr; //錯誤處理 sword fErrorNo; //錯誤號 bool fEof; //在Fetch時候,已經達到最后一個記錄,防止已經讀到最后一個記錄后,又fetch發生的錯誤 bool fBof; //在Open()時候為True,在Next()如果有數據為false;用于判斷用戶是否可以從緩沖區中讀取列值,該部分尚未完成 bool fOpened; //數據集是否打開 #ifdef __DEBUG__ bool bExecuteFlag;#endif};class TOCISession{ public: TOCISession(TOCIDatabase *pDB); ~TOCISession(); void sessionBegin(); void sessionEnd();private: OCISvcCtx *m_hSrvCtx; OCISession *m_hSession; OCIError *m_hError; bool m_bActive; int m_iErrorNo; void checkError();friend class TOCIDirPath;friend class TOCIQuery; };#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -