?? tociquery.h
字號:
#ifndef _OCIQuery_h
#define _OCIQuery_h
#include <oci.h>
#include <stdio.h>
#include <exception.h>
#define __DEBUG__
const int PREFETCH_ROWS = 20; //預先提取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_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 TOCIException : public TException
{
public:
char *GetErrMsg() const;
char *GetErrSrc() const;
public:
TOCIException(sword errNumb, OCIError *err, char *cat, char *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; //錯誤號
};
class TOCIDatabase
{
friend class TOCIQuery;
public:
public:
TOCIDatabase();
~TOCIDatabase();
void SetLogin(char *user, char *password, char *tnsString) ;
bool Connect();
bool Connect(char *usr, char *pwd, char *tns) ;
void Disconnect();
private:
char *usr, *pwd, *tns; //登錄名
bool fConnected; //在Connect中是否連接成功
OCIError *hDBErr;
//OCISvcCtx *hDBSvc; //用于登錄鏈接服務器
OCIEnv *hEnv;
OCIServer *hSvr;
};
class TOCIParam
{
friend class TOCIQuery;
public:
~TOCIParam();
char *name;
int asInteger(); //讀取返回參數值
double asFloat();
long asLong();
char *asString();
bool isNULL();
private:
TOCIParam();
ub2 dataType;
int intValue;
double dblValue; //存儲輸入和輸出的值(緩沖區)
long longValue; //long數據緩沖區
char *stringValue; //字符串返回緩沖區
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();
//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); //返回日期的各個部分
private:
//日期處理
void asDateTimeInternal(int &year, int &month, int &day, int &hour, int &minute, int &second); //返回日期的各個部分,沒有作其他校驗,只是內部調用
TOCIField();
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; //用于讀取列信息
};
class TOCIQuery
{
friend class TOCIField;
public:
//主要功能
void Close(); //關閉SQL語句,以準備接收下一個sql語句
void SetSQL(char *inSqlstmt); //設置Sqlstatement
void Open(int prefetchRows=PREFETCH_ROWS); //打開SQL SELECT語句返回結果集
bool Next(); //移動到下一個記錄
bool Execute(); //執行非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 *fieldName) ; //根據列名(不分大小寫)返回列信息; 建議使用Field(int i)獲得更高的效率
//與參數信息相關
int ParamCount();
TOCIParam& Param(int index); //返回第i個列信息
TOCIParam& Param(char *paramName); //根據列名(不分大小寫)返回列信息; 建議使用Field(int i)獲得更高的效率
//以下是設置參數值
void SetParameter(char *paramName, char* paramValue, bool isOutput = false);
void SetParameter(char *paramName, int paramValue, bool isOutput = false);
void SetParameter(char *paramName, double paramValue, bool isOutput = false) ;
void SetParameter(char *paramName, long paramValue, bool isOutput = false);
void SetParameterNULL(char *paramName);
//constructor & destructor
TOCIQuery(TOCIDatabase *oradb);
~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(char *paramName);//在內部使用,直接返回參數的指針
void CheckError() ; //用于判斷當前的語句是否正確執行,如果有錯誤則把錯誤信息放入errMsg;
int fParamCount; //參數個數
TOCIParam *paramList; //所有參數設置的信息
void GetParamsDef(); //在setSQL時候獲得參數信息
int nTransTimes; //是否曾經執行過Execute()事務操作,以便與回滾.
OCISession *hUser;
//OCITrans* hTrans;
OCIStmt *hStmt; //用于分析sql語句的handle
OCISvcCtx *hSvc; //服務
OCIError *hErr; //錯誤處理
sword fErrorNo; //錯誤號
bool fEof; //在Fetch時候,已經達到最后一個記錄,防止已經讀到最后一個記錄后,又fetch發生的錯誤
bool fBof; //在Open()時候為True,在Next()如果有數據為false;用于判斷用戶是否可以從緩沖區中讀取列值,該部分尚未完成
bool fOpened; //數據集是否打開
#ifdef __DEBUG__
bool bExecuteFlag;
#endif
};
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -