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);}}}
- C++封装SQLite实例<三>
- c++封装SQlite实例
- C++封装SQlite<三>
- C++封装SQLite实例<一>
- C++封装SQLite实例<二>
- C++封装SQLite实例<四>
- C++封装SQLite实例<五>
- C++封装SQLite实例<六>
- VB封装DLL实例(三)
- C++Windows下SQLite简单封装
- Android 深入研究SQLite实例(三)
- SQLite 封装
- sqlite封装
- 实例讲解 封装继承多态(三)
- Cocos2d-x笔记(三)Sqlite数据库封装
- Objective-C SQLite数据库封装FMDB的介绍
- FMDatabase——SQLite的Objective-C封装
- Objective-C SQLite数据库封装FMDB的介绍
- 不安装office导出excel
- mysql大数据导入方法
- 关闭Win8快速启动,解决网卡识别错误/网卡驱动安装不正确的问题
- 测试面试
- 定制CentOS 5安装光盘
- C++封装SQLite实例<三>
- 安全测试与渗透测试区别
- 第一个数组
- 新浪微博的XSS攻击
- 编程随感
- VS快捷键
- Centos建立本地软件源
- Java程序代码调优
- 1383_Binary Numbers