C++封装SQLite实例<三>

来源:互联网 发布:数控车工编程 编辑:程序博客网 时间:2024/06/05 00:13

前一篇博客中介绍的是如何根据sqlite3_get_table()函数来获取一张表的内容,就是一股脑的把表中的内容全部存储起来放在一个一维数组中,这当中的规则已经介绍过了。接下来讲的是如何根据一个SQL查询语句来挑选出合乎选择条件的记录,被挑选出的记录事先是不知道的。你不知道这个查询的结果中有几行更不知道每一行中具体的记录值是什么,所以没办法用给定行值和列值的方式来获取数据,所有之前的用数组存储表的方式就行不通了。想要灵活的管理一个查询返回的结果这就会复杂多了,用到的SQLite原生函数也很多。

这个CppSQLite3Query类中有四个字段,分别是

sqlite3 *mpDB;sqlite3_stmt *mpStmt;bool mbEof;  //由于查询的结果需要一行一行的访问,所以设置一个bool值来表示是否达到最后一行的结尾int mnCols;  //表示这个查询结果的列数,行数是无法得知的
第一个参数:查询要连接的数据库

第二个参数:

** CAPI3REF: SQL Statement Object** KEYWORDS: {prepared statement} {prepared statements}**** An instance of this object represents a single SQL statement.** This object is variously known as a "prepared statement" or a** "compiled SQL statement" or simply as a "statement".**** The life of a statement object goes something like this:**** <ol>** <li> Create the object using [sqlite3_prepare_v2()] or a related**      function.** <li> Bind values to [host parameters] using the sqlite3_bind_*()**      interfaces.** <li> Run the SQL by calling [sqlite3_step()] one or more times.** <li> Reset the statement using [sqlite3_reset()] then go back**      to step 2.  Do this zero or more times.** <li> Destroy the object using [sqlite3_finalize()].** </ol>
是一个SQL语句对象,或是说一条原生的SQL查询语句select * from XXX;经过SQLite处理后就生成了一个sqlite3_stmt对象。以后就可以不用原生的语句来做查询,就直接使用这个sqlite3_stmt*就可以查询了,当查询结束后,要将sqlite3_stmt*指针对象释放掉。

释放函数sqlite3_finalize()和sqlite3_free();函数功能类似,只不过后者是释放sqlite3*对象的,而前者是释放sqlite3_stmt*对象的。

函数原型   SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
函数说明:

/*** CAPI3REF: Destroy A Prepared Statement Object**** ^The sqlite3_finalize() function is called to delete a [prepared statement].** ^If the most recent evaluation of the statement encountered no errors** or if the statement is never been evaluated, then sqlite3_finalize() returns** SQLITE_OK.  ^If the most recent evaluation of statement S failed, then** sqlite3_finalize(S) returns the appropriate [error code] or** [extended error code].**** ^The sqlite3_finalize(S) routine can be called at any point during** the life cycle of [prepared statement] S:** before statement S is ever evaluated, after** one or more calls to [sqlite3_reset()], or after any call** to [sqlite3_step()] regardless of whether or not the statement has** completed execution.**** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op.**** The application must finalize every [prepared statement] in order to avoid** resource leaks.  It is a grievous error for the application to try to use** a prepared statement after it has been finalized.  Any use of a prepared** statement after it has been finalized can result in undefined and** undesirable behavior such as segfaults and heap corruption.*/


用来初始化mnCols字段的函数是:

SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
函数说明:

/*** CAPI3REF: Number Of Columns In A Result Set**** ^Return the number of columns in the result set returned by the** [prepared statement]. ^This routine returns 0 if pStmt is an SQL** statement that does not return data (for example an [UPDATE]).**** See also: [sqlite3_data_count()]*/

在根据列索引值获取当前列的列名用到的函数:

函数原型:SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);


在判断数据是否为空的时候要用到检测数据类型的函数:

函数原型:SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
这个函数返回的是一个整型,其中不同的数值代表不同的已定义好的宏,下面是各种类型:

#define SQLITE_INTEGER  1#define SQLITE_FLOAT    2#define SQLITE_BLOB     4#define SQLITE_NULL     5#ifdef SQLITE_TEXT# undef SQLITE_TEXT#else# define SQLITE_TEXT     3#endif#define SQLITE3_TEXT     3

还有一种查询数据类型的函数

SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
他返回的直接是类型名称。


在获取各种不同类型数据的时候用到各种函数,他们返回不同的数据类型的值:

SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
上面的一些函数可能没有出现在这个封装的C++类中。

下面直接贴代码:

class CppSQLite3Query{private:sqlite3 *mpDB;sqlite3_stmt *mpStmt;bool mbEof;int mnCols;void CheckStmt();public:CppSQLite3Query();CppSQLite3Query(sqlite3 *pdb, sqlite3_stmt *pStmt, bool bEof);CppSQLite3Query(const CppSQLite3Query &rQuery);CppSQLite3Query& operator= (const CppSQLite3Query &rQuery);~CppSQLite3Query();int FieldNums();int FieldIndex(const char* szField);const char* FieldName(int nField);int FieldDataType(int nField);const char* FieldDeclType(int nField);const char* FieldValue(int nField);const char* FieldValue(const char *szField);bool FieldIsNull(int nField);bool FieldIsNull(const char *szField);bool GetIntValue(int nField, int &rDest);bool GetIntValue(const char *szField, int &rDest);bool GetFloatValue(int nField, double &rDest);bool GetFloatValue(const char *szField, double &rDest);bool GetStringValue(int nField, char *&rDest);bool GetStringValue(const char *szField, char *&rDest);bool Eof();void NextRow();void Finalize();};
CppSQLite3Query::CppSQLite3Query(){mpDB = 0;mpStmt = 0;mnCols = 0;mbEof = true;}CppSQLite3Query::CppSQLite3Query(sqlite3 *pdb, sqlite3_stmt *pStmt, bool bEof){mpDB = pdb;mpStmt = pStmt;mbEof = bEof;mnCols = sqlite3_column_count(pStmt);}CppSQLite3Query::CppSQLite3Query(const CppSQLite3Query &rQuery){mpStmt = rQuery.mpStmt;const_cast<CppSQLite3Query &>(rQuery).mpStmt = 0;mnCols = rQuery.mnCols;mbEof = rQuery.mbEof;}CppSQLite3Query& CppSQLite3Query::operator =(const CppSQLite3Query &rQuery){mpStmt = rQuery.mpStmt;const_cast<CppSQLite3Query &>(rQuery).mpStmt = 0;mnCols = rQuery.mnCols;mbEof = rQuery.mbEof;return *this;}CppSQLite3Query::~CppSQLite3Query(){Finalize();}void CppSQLite3Query::CheckStmt(){if (mpStmt == 0){throw CppSQLite3Exception(CPPSQLITE_ERROR,"Invalid Stmt Pointer",DONT_DELETE_MSG);}}int CppSQLite3Query::FieldNums(){CheckStmt();return mnCols;}//根据字段名返回列索引int CppSQLite3Query::FieldIndex(const char* szField){CheckStmt();if (szField){for (int nField = 0; nField < mnCols; nField++){//后面还有很多类似的函数,参数差不多,需要一个sqlite3_stmt*和列索引值,这应该是内部查询了之后返回的结果,而不是事先保存的const char *szTemp = sqlite3_column_name(mpStmt, nField);if (strcmp(szTemp, szField) == 0){return nField;}}}throw CppSQLite3Exception(CPPSQLITE_ERROR,"Invalid field name requested",DONT_DELETE_MSG);}const char* CppSQLite3Query::FieldName(int nField){CheckStmt();if (nField < 0 || nField > mnCols-1){throw CppSQLite3Exception(CPPSQLITE_ERROR,"Invalid field index requested",DONT_DELETE_MSG);}return sqlite3_column_name(mpStmt, nField);}int CppSQLite3Query::FieldDataType(int nField){CheckStmt();if (nField < 0 || nField > mnCols-1){throw CppSQLite3Exception(CPPSQLITE_ERROR,"Invalid field index requested",DONT_DELETE_MSG);}return sqlite3_column_type(mpStmt, nField);}const char* CppSQLite3Query::FieldDeclType(int nField){CheckStmt();if (nField < 0 || nField > mnCols-1){throw CppSQLite3Exception(CPPSQLITE_ERROR,"Invalid field index requested",DONT_DELETE_MSG);}return sqlite3_column_decltype(mpStmt, nField);}const char* CppSQLite3Query::FieldValue(int nField){CheckStmt();if (nField < 0 || nField > mnCols-1){throw CppSQLite3Exception(CPPSQLITE_ERROR,"Invalid field index requested",DONT_DELETE_MSG);}return (const char*)sqlite3_column_text(mpStmt, nField);}const char* CppSQLite3Query::FieldValue(const char *szField){int nField = FieldIndex(szField);return FieldValue(nField);}bool CppSQLite3Query::FieldIsNull(int nField){return (FieldDataType(nField) == SQLITE_NULL);}bool CppSQLite3Query::FieldIsNull(const char *szField){int nField = FieldIndex(szField);return (FieldDataType(nField) == SQLITE_NULL);}bool CppSQLite3Query::GetIntValue(int nField, int &rDest){if (FieldDataType(nField) == SQLITE_NULL){return false;}else{rDest = sqlite3_column_int(mpStmt, nField);return true;}}bool CppSQLite3Query::GetIntValue(const char *szField, int &rDest){int nField = FieldIndex(szField);return GetIntValue(nField, rDest);}bool CppSQLite3Query::GetFloatValue(int nField, double &rDest){if (FieldDataType(nField) == SQLITE_NULL){return false;}else{rDest = sqlite3_column_double(mpStmt, nField);return true;}}bool CppSQLite3Query::GetFloatValue(const char *szField, double &rDest){int nField = FieldIndex(szField);return GetFloatValue(nField, rDest);}bool CppSQLite3Query::GetStringValue(int nField, char *&rDest){if (FieldDataType(nField) == SQLITE_NULL){return false;}else{rDest = const_cast<char *>((const char*)sqlite3_column_text(mpStmt, nField));return true;}}bool CppSQLite3Query::GetStringValue(const char *szField, char *&rDest){int nField = FieldIndex(szField);return GetStringValue(nField, rDest);}bool CppSQLite3Query::Eof(){CheckStmt();return mbEof;}void CppSQLite3Query::NextRow(){CheckStmt();int nRet = sqlite3_step(mpStmt);if (nRet == SQLITE_DONE){// no rowsmbEof = true;}else if (nRet == SQLITE_ROW){// more rows, nothing to do}else{nRet = sqlite3_finalize(mpStmt);mpStmt = 0;const char* szError = sqlite3_errmsg(mpDB);throw CppSQLite3Exception(nRet, szError, DONT_DELETE_MSG);}}void CppSQLite3Query::Finalize(){if (mpStmt){int nRet = sqlite3_finalize(mpStmt);mpStmt = 0;if (nRet != SQLITE_OK){const char* szError = sqlite3_errmsg(mpDB);throw CppSQLite3Exception(nRet, szError, DONT_DELETE_MSG);}}}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老公素质太差怎么办 耿彦波退休了太原怎么办 宫腔镜三天后同房了怎么办 开关失灵关不了怎么办 灯的开关关不掉怎么办? 身上毛孔粗大怎么办呀 脸被牙膏灼伤怎么办 wifi要登录认证怎么办 本科没有选导师怎么办 预授权撤销了怎么办 软件连不上网怎么办 手机屏幕出现有道词典怎么办 孩子总觉得没错怎么办 孩子动手打父母怎么办 初中零基础高中怎么办 弟媳妇爱上我怎么办 孩子考不好家长怎么办 小高考不过关怎么办 小高考不过考生怎么办 江苏不过怎么办小高考 大小脸拍婚纱照怎么办 被大学开除学籍怎么办 大专不给你退学怎么办 大专退学后档案怎么办 多单位同时录取怎么办 毕业学校改名了怎么办 改名后所有档案怎么办 大学学校改名毕业证怎么办 洗碗下水道堵了怎么办 美国打朝鲜丹东怎么办 欧洲通票行程不够怎么办 飞机安检被拦下东西怎么办 火车站丢了东西怎么办 高铁乘务近视怎么办 高铁乘务员怀孕怎么办 小超市生意不好怎么办 企业数字证书过期了怎么办 盆栽植物烂根怎么办 盆栽果树烂根怎么办 盆栽桂花烂根怎么办 月季盆栽烂根怎么办