SQLite是什么
SQLite 是一个独立的、基于文件的、完全开源的 RDBMS(关系数据库管理系统),以其可移植性、可靠性和强大的性能而闻名,即使在低内存环境中也是如此。它的事务符合 ACID 标准,即使在系统崩溃或断电的情况下也是如此。
SQLite 是“无服务器”数据库。SQLite 允许访问数据库的任何进程直接读取和写入数据库磁盘文件。这简化了SQLite的设置过程,因为它消除了配置服务器进程的任何需要。同样,对于将使用SQLite数据库的程序,也不需要进行任何配置:它们所需要的只是访问磁盘。
SQLite是自由的开源软件,使用它不需要特殊的许可证。
SQLite的优点:占用空间小,简单易用,好移植.
SQLite的缺点:有限并发,无用户管理.
什么时候用SQLite:无C/S数据库需求,嵌入式应用,非大量数据,驱动磁盘存取.
C语言接口函数
打开/关闭数据库
int sqlite3_open(
const char *filename, /* [输入]数据库文件名 */
sqlite3 **ppDb) /* [输出]数据库句柄 */);
int sqlite3_close(sqlite3*);//打开时产生的数据库句柄.
一步执行接口
int sqlite3_exec(
sqlite3*, /* 打开时的数据库句柄 */
const char *sql, /* SQL语句 */
int (*callback)(void*,int,char**,char**), /* 极少用,忽略 */
void *, /* 极少用,忽略*/
char **errmsg); /* 极少用,忽略 */
其实到这里你已经可以对数据库做查询,增删改操作了,但是由于sqlite3_exec函数同时解析,编译,执行SQL语句,如果是多次循环语句,都用这个函数执行效率低下,因此增加了预准备语句对象.
步骤是:预准备语句对象的生命周期通常如下所示:
1.使用 sqlite3_prepare_v2() 创建预准备语句对象。
2.使用 sqlite3_bind_*() 将值绑定到参数 接口,*是要绑定的数据类型如:INT。
使用 sqlite3_column_*() 查询结果值,*是要绑定的数据类型如:INT.
3.通过调用 sqlite3_step() 一次或多次来运行 SQL。
4.使用 sqlite3_reset() 重置预准备语句,然后返回 到步骤 2。执行此操作零次或多次。
5.使用 sqlite3_finalize() 销毁对象。
创建预准备语句对象。
int sqlite3_prepare_v2(
sqlite3 *db, /* 打开时的数据库句柄 */
const char *zSql, /* SQL语句 */
int nByte, /*SQL语句长度,负数为自动识别长度 */
sqlite3_stmt **ppStmt, /* [输出]指向预编译语句句柄 */
const char **pzTail /* 为NULL*/
);
将值绑定到参数接口.这类函数有13个,但都差不多,函数名sqlite3_bind_+绑定数据类型比如:
int sqlite3_bind_int(
sqlite3_stmt*, //预编译语句句柄
int, //字段索引,最左侧为1,
int); //要绑定参数的值
就是说
查询结果值.这类函数有13个,但都差不多,函数名sqlite3_column_+绑定类型比如:
const unsigned char *sqlite3_column_text(//返回值:查询的文本
sqlite3_stmt*,//预编译语句句柄
int iCol);//要返回值信息列的索引。结果集最左侧的列的索引为 0。
一次或多次来运行 SQL
int sqlite3_step(sqlite3_stmt*);//预编译语句句柄
返回值:SQLITE_ROW有另一行就绪
重置准备语句,就是说SQL语句有多个步骤,就回到第一步
int sqlite3_reset(sqlite3_stmt *pStmt);//预编译语句句柄
看函数觉得有点糊,举几个例子就更清楚
几个例子
用sqlite3_exec()增加数据记录
void updateDataInfo(int address,int value)// 将指定地址的值更新到数据库
{
sqlite3 *db;
const char * pfilename = "Data.db";
result = sqlite3_open(pfilename, &db);//打开错误,返回值不等于0
if (result != 0)
{
return;
}
char sSQL[200];
sprintf(sSQL, ""INSERT OR REPLACE INTO IntData (address,value) values (%d,%d);"",address,value);//生成SQL语句字符串到sSQL中
sqlite3_exec(db, sSQL, 0, 0, NULL); //执行SQL语句
sqlite3_close(db);
}
用sqlite3_bind_()增加数据记录
void updateDataInfo()// 将指定地址的值更新到数据库
{
sqlite3_stmt *pstmt;
char a[5][2]={0,1, 1,2, 2,3, 3,4, 4,10};
const char *sql = "INSERT INTO IntData (address,value) VALUES(?,?);";
nRet = sqlite3_prepare_v2(pdb, sql, strlen(sql), &pstmt, &pzTail);
int i;
for(i = 0; i < 5; i++){
nCol = 1;
sqlite3_bind_int(pstmt, nCol++, a[i].[0]);//字段address绑定a[0]就是SQL语句的第一个问号
sqlite3_bind_int(pstmt, nCol++, a[i].[1]);//字段value绑定a[1],就是SQL语句的第二个问号
sqlite3_step(pstmt);
sqlite3_reset(pstmt);
}
sqlite3_finalize(pstmt);
}
用sqlite3_column_*()查询数据
getDbInfo()
{
char Data[100];
sqlite3 *pdb;
sqlite3_stmt *pstmt;
char * pfilename = "Data.db";
result = sqlite3_open(pfilename, &pdb);//打开错误,返回值不等于0
char * pSQL = "select * from IntData;"; //SQL语句 从表IntData中查询所有数据
result = sqlite3_prepare_v2(pdb, pSQL, strlen(pSQL), &pstmt, 0);//打开错误,返回值不等于0
while (sqlite3_step(m_stmt) == SQLITE_ROW) //SQLITE_ROW有另一行就绪
{
int address = sqlite3_column_int(pstmt, 0); //读第一个参数
int value = sqlite3_column_int(pstmt, 1);//读第二个参
Data[address] = value;
}
sqlite3_close(db);
}
SQL语法
写几个例子解释
创建一个表名为Log的表,有4个字段,字段名No,为自动递增的整型非空主键,字段名time,不超过20个字符,字段名id与pos为整型.
CREATE TABLE [Log] (\ //创建一个名字叫Log的表
[No] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\//No:字段名称,INTEGER 为整型,NOT NULL PRIMARY KEY AUTOINCREMENT:非空主键递增
[time] VARCHAR(20) NULL,\ //time:字段名称 VARCHAR:最大字符长度为20,无约束
[id] INTEGER NULL,\
[pos] INTEGER NULL,\
)
插入记录:
INSERT OR REPLACE INTO Log //插入或替换到表名Log的表
(No,time,id,pos,opt) //4个字段名称
values (1,'11:45',1,16,1); //插入的值
这里说明一下关键字INSERT OR REPLACE,什么时候执行INSERT,什么时候执行REPLACE呢,要看创建表的时候的约束,创建Log表的字段No的约束为非空主键,如果表中字段No有1,就执行replace操作,否则执行insert操作.
查询语句:
SELECT time FROM Log\ //从表Log中查询字段time
WHERE pos = 16 AND opt = 1; //条件是pos为16,opt为 1
查询结果为插入的11:45.
生成库文件
如果你要动态库可以直接从官网下载,SQLite Download Page
如果你需要sqlite静态库可参考以下文章:
其第3步应用静态库.lib,就省去5,6,7步直接生成.lib.如果按照写的操作出现"C1853"错误,只要在项目属性页,C/C++/预编译头//预编译头设置为"不使用预编译头"即可编译通过.