📄 tdbquery.h
字号:
#ifndef _OCIQuery_h
#define _OCIQuery_h
#include "TException.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <oci.h>
#include <oratypes.h>
#include <ocidfn.h>
#include <ocidem.h>
#include <ociapr.h>
#include <oci.h>
/*备注:所有SIZE宏定义考虑+1*/
#ifndef SIZE_DATE_TIME
#define SIZE_DATE_TIME 15 //日期时间格式大小YYYYMMDDHHMISS
#endif //SIZE_DATE_TIME
#ifndef SIZE_DATE_TIME_FULL
#define SIZE_DATE_TIME_FULL 20 //日期时间格式大小为YYYY?MM?DD HH?MI?SS
#endif
extern int SqlDone();
#ifdef boolean
#undef boolean
#endif
#ifdef WIN32
#pragma warning(disable: 4290)
#pragma warning(disable: 4267)
#endif
#ifdef WIN32
//#ifndef int64
// #define int64 long long
//#endif
#ifndef llong
#define llong long long
#endif
#else
#ifdef LONG64
#ifndef int64
#define int64 long
#endif
#ifndef llong
#define llong long
#endif
#else
#ifndef int64
#define int64 long long
#endif
#ifndef llong
#define llong long long
#endif
#endif
#endif
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_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 TDBException("TDBQuery(TDBDatabase &db)", ERR_GENERAL, "Can not declare a TDBQuery when the database is not connected");
const char* const ERR_INDEX_OUT_OF_BOUND = "%s"; //throw TDBException(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 TDBException(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 TDBException(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 TDBException(fParentQuery->fSqlStmt, ERR_NOMORE_MEMORY_BE_ALLOCATED, "asBlobBuffer()", __LINE__);
const char* const ERR_FILE_IO = "%s: can not open file:%s"; //throw TDBException(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 TDBException(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 TDBException(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 TDBException;
class TDBDatabase;
class TDBQuery;
class TDBField;
class TDBParam;
class TDBSession;
class TDBDirPath; //define in TDBDirPath.h
class TDBException : public TException
{
public:
char *GetErrMsg() const;
char *GetErrSql() const;
public:
TDBException(sword errNumb, OCIError *err,const char *cat,const char *sql);//执行OCI函数发生的错误
TDBException(const char *sql, const char* errFormat, ...);
virtual ~TDBException();
private:
char errCategory[MAX_ERR_CAT_LENGTH+1]; //错误分类
text errMessage[MAX_ERRMSG_LENGTH+1]; //错误信息
char errSQL[MAX_SQLSTMT_LENGTH+1]; //发生错误的sql语句
int errNo; //错误号
};
class TDBDatabase
{
friend class TDBQuery;
friend class TDBSession;
friend class TDBDirPath;
public:
public:
TDBDatabase() ;
virtual ~TDBDatabase();
void SetLogin(char *user, char *password, char *tnsString) ;
bool Connect() ;
bool Connect(char *usr, char *pwd, char *tns) ;
void Disconnect() ;
void TransBegin();
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 TDBParam
{
friend class TDBQuery;
public:
virtual ~TDBParam();
char *name;
int AsInteger() ; //读取返回参数值
double AsFloat() ;
long AsLong() ;
char* AsString() ;
bool isNULL() ;
private:
TDBParam();
ub2 dataType;
int intValue;
double dblValue; //存储输入和输出的值(缓冲区)
long longValue; //long数据缓冲区
char *stringValue; //字符串返回缓冲区
int * intArray; //INT数组
double * dblArray; //DOUBLE数组
long * longArray; //LONG数组
long long * llongArray; //LONG LONG数组
char ** stringArray; //STRING数组
int stringSize; //string数组中的string大小
bool fIsOutput; //是否是输出参数.默认是输入参数
sb2 indicator; //在返回值时候是否为空
OCIBind *hBind;
};
class TDBField
{
friend class TDBQuery;
public:
virtual ~TDBField();
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() ;
llong 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) ; //返回日期的各个部分,没有作其他校验,只是内部调用
TDBQuery *fParentQuery; //指向该Field所属于的Query
TDBField();
//数据缓冲区,分别为字符串、整数、浮点数分配空间
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 TDBQuery
{
friend class TDBField;
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 TransBegin(); //事务开启
bool Commit(); //事务提交
bool Rollback(); //事务回滚
int RowsAffected() { return fTotalRowsFetched;}; //DELETE/UPDATE/INSERT语句修改的记录数目
int GetSQLCode() { return fErrorNo;}; //返回Oracle执行结果代码
//与列信息相关
int FieldCount() ; //总共有几个列
TDBField& Field(int index) ; //返回第i个列信息
TDBField& Field(const char *fieldName) ; //根据列名(不分大小写)返回列信息; 建议使用Field(int i)获得更高的效率
//与参数信息相关
int ParamCount() ;
TDBParam& Param(int index) ; //返回第i个列信息
TDBParam& Param(const char *paramName) ; //根据列名(不分大小写)返回列信息; 建议使用Field(int i)获得更高的效率
//以下是设置参数值
void SetParameter(const char *paramName, const char* paramValue) ;
void SetParameter(const char *paramName, const char paramValue) ; //add by fu.wenjun@20041125
void SetParameter(const char *paramName, int paramValue);
void SetParameter(const char *paramName, double paramValue);
void SetParameter(const char *paramName, long paramValue);
void SetParameter(const char *paramName, long long paramValue) ;
void SetParameterNULL(const char *paramName) ;
/*备注:增加int iArraySize=0为了兼容Informix部分的同名函数,OCI部分不进行任何处理*/
//数组操作
void SetParamArray(const char *paramName, char ** paramValue, int iStructSize, int iStrSize ,int iArraySize=0,bool isOutput = false) ;
void SetParamArray(const char *paramName, int * paramValue, int iStructSize, int iArraySize=0,bool isOutput = false) ;
void SetParamArray(const char *paramName, double * paramValue, int iStructSize, int iArraySize=0,bool isOutput = false) ;
void SetParamArray(const char *paramName, long * paramValue, int iStructSize, int iArraySize=0,bool isOutput = false) ;
void SetParamArray(const char *paramName, long long * paramValue, int iStructSize, int iArraySize=0,bool isOutput = false) ;
//constructor & destructor
TDBQuery(TDBDatabase *oradb) ;
TDBQuery(TDBDatabase *oradb,TDBSession *session) ;
virtual ~TDBQuery();
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; //字段个数
TDBDatabase *db; //此query属于哪个Dabase,在Constructor中创建
TDBField *fieldList; //在内部保存的所有字段信息
void GetFieldsDef() ; //获得字段信息,并为字段分配取值的缓冲区
TDBParam *ParamByName(const char *paramName) ;//在内部使用,直接返回参数的指针
void CheckError() ; //用于判断当前的语句是否正确执行,如果有错误则把错误信息放入errMsg;
int fParamCount; //参数个数
TDBParam *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 TDBSession
{
public:
TDBSession(TDBDatabase *pDB);
virtual ~TDBSession();
void sessionBegin();
void sessionEnd();
private:
OCISvcCtx *m_hSrvCtx;
OCISession *m_hSession;
OCIError *m_hError;
bool m_bActive;
int m_iErrorNo;
void CheckError();
friend class TDBDirPath;
friend class TDBQuery;
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -