sqlite数据库操作类使用说明-基础篇
本文主要演示sqlite数据库类的基础用法。
本篇数据库类使用c++进行封装,但导出了C语言接口,本文测试代码使用的是C语言用法,c++用法基本一致,集成了一些常用的宏定义以及不常用的宏定义用法。
先上测试代码:
#include <Wdebug.h>
#include <stdio.h>
#include <sqlite/Wsqlite.h>
#include <stdlib.h>
#define TABLE_NAME "TEST_base"
extern int callback(void* pdata, int argc, char** argv, char** azColName);
void test_base(int argc, char* argv[])
{
struct TsqlQuery* parse = NULL;
struct TsqlCtrl* This = CreateSqlCtrl("database.db");
if (This != NULL) {
Wlog("创建表");
TsqlCtrlExec (This, SQLCMD_DROP_TABLE(TABLE_NAME), NULL, NULL);
TsqlCtrlExec(This, SQLCMD_CREATE_TABLE(TABLE_NAME,
"ID INTEGER PRIMARY KEY AUTOINCREMENT, "
"NAME TEXT NOT NULL, "
"AGE INT NOT NULL, "
"ADDRESS CHAR(50), "
"SALARY REAL"), NULL, NULL);
Wlog ("字段AGE:%s", TsqlCtrlCheckField(This, TABLE_NAME, "AGE")?"存在":"不存在");
Wlog ("字段AAAAAA:%s", TsqlCtrlCheckField(This, TABLE_NAME, "AAAAAA")?"存在":"不存在");
//Wlog ("查询索引:%d", TsqlCtrlRecordCnt(This, "SELECT COUNT(*) AS Cnt FROM sqlite_master WHERE type='index' AND name='test_idx'"));
if (TsqlCtrlRecordCnt(This, SQLCMD_IDX_EXIST("test_idx"))==0) {//判断索引是否存在
Wlog ("创建索引!");
TsqlCtrlExec(This, SQLCMD_CREATE_IDX(TABLE_NAME, "test_idx", "ID"), NULL, NULL);
}
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME" (ID,NAME,AGE,ADDRESS,SALARY) VALUES(1, '张三', 18, '珠海', 2500.0);", NULL, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME" (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '李四', 21, '广州', 6080.0);", NULL, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME" (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '啊五', 30, '深圳', 10800.0);", NULL, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME" (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '小哀', 10, '珠海', 0.0);", NULL, NULL);
TsqlCtrlExec(This, "SELECT * FROM "TABLE_NAME " WHERE AGE>10;", callback, NULL);
Wlog ("record=%d", TsqlCtrlRecordCnt (This, SQLCMD_RECORDCNT(TABLE_NAME)));
//TUint32 RecordCnt = TsqlCtrlRecordCnt (This, SQLCMD_RECORDCNT(TABLE_NAME));
TsqlCtrlExec(This, "UPDATE " TABLE_NAME " SET AGE=31 WHERE NAME='啊五'", NULL, NULL);
TsqlCtrlExec(This, "SELECT AGE, NAME FROM "TABLE_NAME, callback, NULL);
TsqlCtrlExec(This, "DELETE FROM "TABLE_NAME" WHERE SALARY<3000.0", NULL, NULL);
TsqlCtrlExec(This, "SELECT NAME, AGE FROM "TABLE_NAME " WHERE ID>0;", callback, NULL);
Wlog("当前记录数为:%d", TsqlCtrlRecordCnt(This, "SELECT COUNT(*) AS Cnt FROM "TABLE_NAME));
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME " (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '小刘', 28, '梅州', 8500.32);", NULL, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME" (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '小张', 29, '深圳', 7500.25);", NULL, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME " (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '小雪', 40, '广州', 10080.46);", NULL, NULL);
Wlog("当前记录数为:%d", TsqlCtrlRecordCnt(This, "SELECT COUNT(*) AS Cnt FROM "TABLE_NAME));
TsqlCtrlExec(This, "SELECT * FROM "TABLE_NAME, callback, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME " (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '小吴', 23, '上海', 9600.0);", NULL, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME " (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '阿奇', 35, '北京', 8500.21);", NULL, NULL);
TsqlCtrlExec(This, "INSERT INTO "TABLE_NAME " (ID,NAME,AGE,ADDRESS,SALARY) VALUES(NULL, '志勇', 29, '长沙', 6800.69);", NULL, NULL);
TsqlCtrlExec(This, "SELECT * FROM "TABLE_NAME " WHERE SALARY>3000.0;", callback, NULL);
parse = TsqlCtrlQuery(This, "SELECT * FROM "TABLE_NAME " WHERE SALARY>3000.0;");
if (parse) {
Wlog("跳转到记录2!");
TsqlQueryBegin (parse);
TsqlQueryNext (parse);
TsqlQueryNext (parse);
Wlog("记录2 NAME = %s", TsqlQueryGetString(parse, "NAME", ""));
Wlog("下一条记录:%d", TsqlQueryNext(parse));
Wlog("记录3 NAME = %s", TsqlQueryGetString(parse, "NAME", ""));
Wlog("记录3 SALARY = %lf", TsqlQueryGetFloat(parse, "SALARY", 0.0));
Wlog("上一条记录:%d", TsqlQueryLast(parse));
Wlog("记录2 NAME = %s", TsqlQueryGetString(parse, "NAME", ""));
Wlog("记录2 SALARY = %f", TsqlQueryGetFloat(parse, "SALARY", 0.0));
Wlog("跳到首记录");
TsqlQueryBegin(parse);
Wlog("记录0 NAME = %s", TsqlQueryGetString(parse, "NAME", ""));
Wlog("记录0 SALARY = %f", TsqlQueryGetFloat(parse, "SALARY", 0.0));
Wlog("跳到末记录");
TsqlQueryEnd (parse);
Wlog("记录末尾 NAME = %s", TsqlQueryGetString(parse, "NAME", ""));
Wlog("记录末尾 SALARY = %f", TsqlQueryGetFloat(parse, "SALARY", 0.0));
Wlog("记录末尾 ID = %ld", TsqlQueryGetNumber(parse, "ID", 0));
Wlog("记录末尾(默认空) NAME = %s", TsqlQueryGetString(parse, "name", "morenzhi"));
Wlog ("遍历记录:\n");
TsqlQueryBegin (parse);
do {
Wlog ("id:%ld;name:%s;age:%ld;address:%s;salary:%f",
TsqlQueryGetNumber(parse, "ID", 0)
,TsqlQueryGetString(parse, "NAME", "(null)")
,TsqlQueryGetNumber(parse, "AGE", 0)
,TsqlQueryGetString(parse, "ADDRESS", "(null)")
,TsqlQueryGetFloat(parse, "SALARY", 0.0)
);
} while (TsqlQueryNext (parse) > 0);
printf ("\n");
TsqlQueryDestroy(parse);
}
// Wlog("表 "TABLE_NAME" %s!", TsqlCtrlCheckTable(This, TABLE_NAME) == WSQLITE_TRUE ? "存在" : "不存在");
// TsqlCtrlDelTable(This, TABLE_NAME);
// Wlog("表 "TABLE_NAME" %s!", TsqlCtrlCheckTable(This, TABLE_NAME) == WSQLITE_TRUE?"存在":"不存在");
// Wlog("销毁");
TsqlCtrlDestroy(This);
}
}
这些都为最基本的创建表、插入记录、删除记录、查询记录等操作。
开头先创建数据库操作句柄(实质上是类指针);
下面是相关头文件
/***c++头文件***/
#ifndef __W_SQL_SQLITE_HPP
#define __W_SQL_SQLITE_HPP
#include <sqlite/sqlite3.h>
#include <sqlite/WsqlQuery.hpp>
#include <sqlite/WsqlBlob.hpp>
#include <sqlite/WsqlCmd.h>
#include <mutex>
/***********************************************************
* 功 能:
* 查询结果回调函数。
*
* 参 数
* pdata:用户传入参数指针
* argc:成员数
* argv:查询结果对应成员值指针地址
* azColName:查询结果对应成员名指针地址
*
* 返 回 值
* 0:继续查找
* 非0:终止查找(sqlite3_exec返回SQLITE_ABORT错误)
***********************************************************/
#ifndef WsqlCallBack
typedef int WsqlCallBack(void* pdata, int argc, char** argv, char** azColName);
#endif
/***********************************************************
* 功 能:事务回调函数。调用事务处理时传入的回调函数
*
* 注 意: 在事务的回调函数中必须使用未加锁的数据库操作函数!
* 否则会产生死锁!
*
* 参 数:调用事务处理时传入的指针
*
* 返 回 值
* TRUE:提交事务,执行COMMIT/END TRANSACTION
* FALSE:回滚事务,执行ROLLBACK
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
#ifndef WsqlTransactionCallBack
typedef TBool WsqlTransactionCallBack(void* pdata);
#endif
#endif
namespace sql {
typedef enum {
True,//成功
False,//失败
} Ret;
class sqlite {
public:
/***********************************************************
* 功 能:
* 数据库操作构造函数
*
* 参 数
* filename:打开的数据库文件名
*
* 返 回 值
* 无
***********************************************************/
sqlite (const char* const filename);
/***********************************************************
* 功 能:
* 数据库操作析构函数
*
* 参 数
* 无
*
* 返 回 值
* 无
***********************************************************/
~sqlite ();
private:
sqlite3* db = nullptr;
std::mutex mtx;
/***********************************************************
* 功 能:
* 打开数据库。
*
* 参 数
* filename:数据库文件名
*
* 返 回 值
* TRUE:成功
* FALSE:失败
***********************************************************/
TBool Open (const char* const filename);
/***********************************************************
* 功 能:
* 关闭数据库。
*
* 参 数
* 无
*
* 返 回 值
* 无
***********************************************************/
void Close (void);
public:
/***********************************************************
* 功 能:
* 未加锁的数据库语句执行函数。
*
* 参 数
* sql:数据库完整语句
* func:数据库回调函数,可为NULL
* param:回调函数入口参数,可为NULL
*
* 返 回 值
* 参考enum Ret
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
Ret ExecNoMutex (const char* const sql, WsqlCallBack func, void* param);
#endif
/***********************************************************
* 功 能:
* 数据库语句执行函数
*
* 参 数
* sql:数据库完整语句
* func:数据库回调函数,可为NULL
* param:回调函数入口参数,可为NULL
*
* 返 回 值
* 参考enum Ret
***********************************************************/
Ret Exec (const char* const sql, WsqlCallBack func, void* param);
/***********************************************************
* 功 能:
* 事务处理。
*
* 参 数
* func:事务回调函数,不可为NULL
* param:回调函数入口参数,可为NULL
*
* 返 回 值
* 无
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
TBool Transaction (WsqlTransactionCallBack func, void* param);
#endif
/***********************************************************
* 功 能:(未加锁)
* 查询记录数:此接口做了限制
* 查询语句模板:SELECT COUNT(*) AS Cnt FROM table_name WHERE rowid<10
* 必须有AS Cnt 因为查询时通过搜索Cnt字段读取结果,
*
* 参 数
* SqlCmd:查询语句
*
* 返 回 值
* 查询结果。
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
TUint32 RecordCntNoMutex (const char* const SqlCmd);
#endif
/***********************************************************
* 功 能:
* 查询记录数:此接口做了限制
* 查询语句模板:SELECT COUNT(*) AS Cnt FROM table_name WHERE rowid<10
* 必须有AS Cnt 因为查询时通过搜索Cnt字段读取结果,
*
* 参 数
* SqlCmd:查询语句
*
* 返 回 值
* 查询结果。
***********************************************************/
TUint32 RecordCnt (const char* const SqlCmd);
/***********************************************************
* 功 能:
* 检查字段名是否存在。
*
* 参 数
* table_anme:表名
* Filed_name:字段名
*
* 返 回 值
* TRUE:存在
* FALSE:不存在
***********************************************************/
TBool CheckField (const char* const table_anme, const char* const Filed_name);
/***********************************************************
* 功 能:
* 查询表(未加锁)
*
* 参 数
* sql:查询语句
*
* 返 回 值
* 成功:返回查询结果类指针
* 失败:NULL
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
class Query* QueryNoMutex(const char* const sql);
#endif
/***********************************************************
* 功 能:
* 查询表
*
* 参 数
* sql:查询语句
*
* 返 回 值
* 成功:返回查询结果类指针
* 失败:NULL
***********************************************************/
class Query* Query(const char* const sql);
/***********************************************************
* 功 能:
* 写blob数据(未加锁)
*
* 参 数
* sqlCmd:sql命令
* data:传入存储容器以及须获取的列号
*
* 返 回 值
* 参考enum Ret
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
Ret WriteBlobNoMutex (const char* const sqlCmd, class blob* data);
#endif
/***********************************************************
* 功 能:
* 写blob数据
*
* 参 数
* sqlCmd:sql命令
* data:传入存储容器以及须获取的列号
*
* 返 回 值
* 参考enum Ret
***********************************************************/
Ret WriteBlob (const char* const sqlCmd, class blob* data);
/***********************************************************
* 功 能:
* 读blob数据
* 注意:此接口返回为NULL时即已销毁传入的data
*
* 参 数
* sqlCmd:sql命令
* data:传入存储容器以及须获取的列号
*
* 返 回 值
* 返回读出的数据。
***********************************************************/
class blob* ReadBlob (const char* const sqlCmd, class blob* data);
};
}
#endif
/***c接口头文件***/
#ifndef __WSQLITE_H
#define __WSQLITE_H
#include <Tdatatype.h>
#include <sqlite/WsqlQuery.h>
#include <sqlite/WsqlBlob.h>
#include <sqlite/WsqlCmd.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
WSQLITE_TRUE,//成功
WSQLITE_FALSE,//失败
} TsqlRet;
struct TsqlCtrl;
/***********************************************************
* 功 能:
* 查询结果回调函数。
*
* 参 数
* pdata:用户传入参数指针
* argc:成员数
* argv:查询结果对应成员值指针地址
* azColName:查询结果对应成员名指针地址
*
* 返 回 值
* 0:继续查找
* 非0:终止查找(sqlite3_exec返回SQLITE_ABORT错误)
***********************************************************/
#ifndef WsqlCallBack
typedef int WsqlCallBack(void* pdata, int argc, char** argv, char** azColName);
#endif
/***********************************************************
* 功 能:事务回调函数。调用事务处理时传入的回调函数
*
* 注 意: 在事务的回调函数中必须使用未加锁的数据库操作函数!
* 否则会产生死锁!
*
* 参 数:调用事务处理时传入的指针
*
* 返 回 值
* TRUE:提交事务,执行COMMIT/END TRANSACTION
* FALSE:回滚事务,执行ROLLBACK
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
#ifndef WsqlTransactionCallBack
typedef TBool WsqlTransactionCallBack(void* pdata);
#endif
#endif
/***********************************************************
* 功 能:
* 数据库语句执行函数(未加锁)
*
* 参 数
* sqlCmd:数据库完整语句
* func:数据库回调函数,可为NULL
* param:回调函数入口参数,可为NULL
*
* 返 回 值
* 参考TsqlRet
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
TsqlRet TsqlCtrlExecNoMutex (struct TsqlCtrl* This, const char* const sqlCmd, WsqlCallBack func, void* param);
#endif
/***********************************************************
* 功 能:
* 数据库语句执行函数
*
* 参 数
* sqlCmd:数据库完整语句
* func:数据库回调函数,可为NULL
* param:回调函数入口参数,可为NULL
*
* 返 回 值
* 参考TsqlRet
***********************************************************/
TsqlRet TsqlCtrlExec (struct TsqlCtrl* This, const char* const sqlCmd, WsqlCallBack func, void* param);
/***********************************************************
* 功 能:
* 事务处理。
*
* 参 数
* func:事务回调函数,不可为NULL
* param:回调函数入口参数,可为NULL
*
* 返 回 值
* 无
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
TBool TsqlCtrlTransaction (struct TsqlCtrl* This, WsqlTransactionCallBack func, void* param);
#endif
/***********************************************************
* 功 能(未加锁)
* 查询记录数:此接口做了限制
* 查询语句模板:SELECT COUNT(*) AS Cnt FROM table_name WHERE rowid<10
* 必须有AS Cnt 因为查询时通过搜索Cnt字段读取结果,
*
* 参 数
* SqlCmd:查询语句
*
* 返 回 值
* 查询结果。
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
TUint32 TsqlCtrlRecordCntNoMutex (struct TsqlCtrl* This, const char* const SqlCmd);
#endif
/***********************************************************
* 功 能
* 查询记录数:此接口做了限制
* 查询语句模板:SELECT COUNT(*) AS Cnt FROM table_name WHERE rowid<10
* 必须有AS Cnt 因为查询时通过搜索Cnt字段读取结果,
*
* 参 数
* SqlCmd:查询语句
*
* 返 回 值
* 查询结果。
***********************************************************/
TUint32 TsqlCtrlRecordCnt (struct TsqlCtrl* This, const char* const SqlCmd);
/***********************************************************
* 功 能
* 检查字段名是否存在。
*
* 参 数
* table_anme:表名
* Filed_name:字段名
*
* 返 回 值
* TRUE:存在
* FALSE:不存在
***********************************************************/
TBool TsqlCtrlCheckField (struct TsqlCtrl* This, const char* const table_anme, const char* const Filed_name);
/***********************************************************
* 功 能:
* 查询表(未加锁)
*
* 参 数
* sql:查询语句
*
* 返 回 值
* 成功:返回查询结果类指针
* 失败:NULL
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
struct TsqlQuery* TsqlCtrlQueryNoMutex(struct TsqlCtrl* This, const char* const sql);
#endif
/***********************************************************
* 功 能:
* 查询表
*
* 参 数
* sql:查询语句
*
* 返 回 值
* 成功:返回查询结果类指针
* 失败:NULL
***********************************************************/
struct TsqlQuery* TsqlCtrlQuery(struct TsqlCtrl* This, const char* const sql);
/***********************************************************
* 功 能:
* 写blob数据(未加锁)
*
* 参 数
* sqlCmd:sql命令
* data:写入数据
*
* 返 回 值
* WSQLITE_TRUE:写入成功
* 其他:参考TsqlRet
***********************************************************/
#ifdef WSQLITE_ENABLE_NOMUTEX
TsqlRet TsqlCtrlWriteBlobNoMutex (struct TsqlCtrl* This, const char* const sqlCmd, struct TsqlBlob* data);
#endif
/***********************************************************
* 功 能:
* 写blob数据
*
* 参 数
* sqlCmd:sql命令
* data:写入数据
*
* 返 回 值
* WSQLITE_TRUE:写入成功
* 其他:参考TsqlRet
***********************************************************/
TsqlRet TsqlCtrlWriteBlob (struct TsqlCtrl* This, const char* const sqlCmd, struct TsqlBlob* data);
/***********************************************************
* 功 能:
* 读取blob数据
* 注意:此接口返回为NULL时即已销毁传入的data
*
* 参 数
* sqlCmd:sql命令
* data:传入存储容器以及须获取的列号
*
* 返 回 值
* 成功:返回查询结果类指针
* 失败:NULL
***********************************************************/
struct TsqlBlob* TsqlCtrlReadBlob (struct TsqlCtrl* This, const char* const sqlCmd, struct TsqlBlob* data);
/***********************************************************
* 功 能:
* 注销数据库控制类
*
* 参 数
*
* 返 回 值
***********************************************************/
void TsqlCtrlDestroy (struct TsqlCtrl* This);
//#define TsqlCtrlDestroy(PCLASS_ADDR) free (PCLASS_ADDR)
/***********************************************************
* 功 能:
* 创建数据库控制类
*
* 参 数
* pfilename:打开的数据库文件名
*
* 返 回 值
* 成功:返回类指针
* 失败:NULL
***********************************************************/
struct TsqlCtrl* CreateSqlCtrl (const char* pfilename);
#ifdef __cplusplus
}
#endif
#endif
测试案例中database.db为打开或创建的数据库文件名,打开或创建成功将返回打开的数据库句柄,失败则返回NULL。
函数TsqlCtrlExec为数据库语句执行函数,对原始API未做多余操作,最主要的是添加了线程锁,而传入的数据库语句中SQLCMD_DROP_TABLE(TABLE_NAME)为删除数据库中的表;其原型为见下文头文件。SQLCMD_CREATE_TABLE()宏则为创建表的语句(使用宏纯属懒人使用,只为少敲几行代码。宏可以留下一遍日后某些不常用用法忘记了可以回头看看宏定义)。
下面是一些常用命令的宏定义:
#ifndef __WSQLCMD_H
#define __WSQLCMD_H
// 开关宏
#define WSQLITE_ENABLE_NOMUTEX
//SQL 语句
//创建表
#define SQLCMD_CREATE_TABLE(TABLE_NAME,MEMBER) "CREATE TABLE IF NOT EXISTS " TABLE_NAME " (" MEMBER ");"
//删除表
//#define SQLCMD_DROP_TABLE(TABLE_NAME) "DROP IF EXISTS TABLE " TABLE_NAME ";"
#define SQLCMD_DROP_TABLE(TABLE_NAME) "DROP TABLE " TABLE_NAME ";"
//检查表是否存在
#define SQLCMD_CHECK_TABLE(TABLE_NAME) "SELECT COUNT(*) AS Cnt FROM sqlite_master where type='table' and name='" TABLE_NAME "';"
//查询记录数
#define SQLCMD_RECORDCNT(TABLE_NAME) "SELECT COUNT(*) AS Cnt FROM " TABLE_NAME
#define SQLCMD_RECORDCNTEX(TABLE_NAME,DONDITION) "SELECT COUNT(*) AS Cnt FROM " TABLE_NAME " WHERE " DONDITION
//将表中的rowid自增序列归零,下一次插入记录的行号从当前设置的0+1开始,注意:seq的值不能小于当前最大的rowid
#define SQLCMD_CLEAR_TABLE_ROWID(TABLE_NAME) "UPDATE sqlite_sequence SET seq=0 WHERE name='" TABLE_NAME "';"
//查询表字段等信息
/***************
* 判断 pk 列是否为1,name即为主键列名
***************/
#define SQLCMD_TABLEINFO(TABLE_NAME) "PRAGMA table_info(" TABLE_NAME ");"
//重命名表
#define SQLCMD_RENAME_TABLE(OLD_NAME,NEW_NAME) "ALTER TABLE " OLD_NAME " RENAME TO " NEW_NAME
// 增加表中字段
#define SQLCMD_ADD_COLUMN(TABLE_NAME,TABLE_FIELD) "ALTER TABLE " TABLE_NAME " ADD COLUMN " TABLE_FIELD
// 创建索引
#define SQLCMD_CREATE_IDX(TABLE_NAME,IDX_NAME,IDX_PARAM) "CREATE INDEX IF NOT EXISTS " IDX_NAME " ON " TABLE_NAME " (" IDX_PARAM ") ;"
//#define SQLCMD_CREATE_IDX(TABLE_NAME,IDX_NAME,IDX_PARAM) "CREATE INDEX " IDX_NAME " ON " TABLE_NAME " (" IDX_PARAM ") ;"
// 查询索引是否存在
#define SQLCMD_IDX_EXIST(IDX_NAME) "SELECT COUNT(*) AS Cnt FROM sqlite_master WHERE type='index' AND name='" IDX_NAME "'"
// 删除索引
#define SQLCMD_DROP_IDX(IDX_NAME) "DROP INDEX " IDX_NAME
#endif
有时我们更新升级软件时,可能需要为已有的表添加某个字段,此时我们就需要检测某个字段是否已存在。此数据库类封装了字段检查函数TsqlCtrlCheckField,传入表名及字段名即可返回是否存在。
创建好数据库和表之后,插入一系列记录,最常用的查询则使用TsqlCtrlQuery函数进行,查询结构通过返回值返回数据库查询结果句柄。查询失败或未查询到记录则返回NULL,如例程中所示。
测试代码运行结果如下:
创建表
字段AGE:存在
字段AAAAAA:不存在
创建索引!
ID = 1
NAME = 张三
AGE = 18
ADDRESS = 珠海
SALARY = 2500.0
ID = 2
NAME = 李四
AGE = 21
ADDRESS = 广州
SALARY = 6080.0
ID = 3
NAME = 啊五
AGE = 30
ADDRESS = 深圳
SALARY = 10800.0
record=4
AGE = 18
NAME = 张三
AGE = 21
NAME = 李四
AGE = 31
NAME = 啊五
AGE = 10
NAME = 小哀 = 31
ADDRESS = 深圳
SALARY = 10800.0
ID = 5
NAME = 小刘
AGE = 28
ADDRESS = 梅州
SALARY = 8500.32
ID = 6
NAME = 小张
AGE = 29
ADDRESS = 深圳
SALARY = 7500.25
ID = 7
NAME = 小雪
AGE = 40
ADDRESS = 广州
SALARY = 10080.46
ID = 2
NAME = 李四
AGE = 21
ADDRESS = 广州
SALARY = 6080.0
ID = 3
NAME = 啊五
AGE = 31
ADDRESS = 深圳
SALARY = 10800.0
ID = 5
NAME = 小刘
AGE = 28
ADDRESS = 梅州
SALARY = 8500.32
ID = 6
NAME = 小张
AGE = 29
ADDRESS = 深圳
SALARY = 7500.25
ID = 7
NAME = 小雪
AGE = 40
ADDRESS = 广州
SALARY = 10080.46
ID = 8
NAME = 小吴
AGE = 23
ADDRESS = 上海
SALARY = 9600.0
ID = 9
NAME = 阿奇
AGE = 35
ADDRESS = 北京
SALARY = 8500.21
ID = 10
NAME = 志勇
AGE = 29
ADDRESS = 长沙
SALARY = 6800.69
跳转到记录2!
记录2 NAME = 小刘
下一条记录:4
记录3 NAME = 小张
记录3 SALARY = 7500.250000
上一条记录:3
记录2 NAME = 小刘
记录2 SALARY = 8500.320000
跳到首记录
记录0 NAME = 李四
记录0 SALARY = 6080.000000
跳到末记录
记录末尾 NAME = 志勇
记录末尾 SALARY = 6800.690000
记录末尾 ID = 10
记录末尾(默认空) NAME = 志勇
遍历记录:
id:2;name:李四;age:21;address:广州;salary:6080.000000
id:3;name:啊五;age:31;address:深圳;salary:10800.000000
id:5;name:小刘;age:28;address:梅州;salary:8500.320000
id:6;name:小张;age:29;address:深圳;salary:7500.250000
id:7;name:小雪;age:40;address:广州;salary:10080.460000
id:8;name:小吴;age:23;address:上海;salary:9600.000000
id:9;name:阿奇;age:35;address:北京;salary:8500.210000
id:10;name:志勇;age:29;address:长沙;salary:6800.690000
头文件及源代码中含有大量注释,这里就不做多余说明了~