交叉编译sqlite3请关注我第一篇博文
sqlite3 交叉编译-CSDN博客
sqlite3的命令的简单使用(增删改查,创建/删除表)请关注我的上一篇博文
sqlite3嵌入式使用以及C/C++代码开发-CSDN博客
一、新建文件夹
此文件夹用于放置工程,比如我的文件夹叫sqliteDemo,将交叉编译编译好的sqlite3的lib文件夹和头文件放置在工程目录下
sqliteDemo文件夹下文件如下
二、创建测试文件
创建一个c文件,比如我的为main.c
在C文件中写入如下内容
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"int main(void)
{sqlite3 *ppdb;int ret = sqlite3_open("student.db",&ppdb);if(ret != SQLITE_OK){printf("sqlite3_open Failed -- %s\n", sqlite3_errmsg(ppdb));exit(1);}return 0;
}
三、编译测试
执行命令 arm-linux-gnueabihf-gcc main.c -o sql -L./lib -lsqlite3
则生成一个命令 sql 的可执行文件
四、运行
将sql拷贝到开发板中的某个位置,执行 ./sql 即可运行
五、sqlite函数说明
sqlite3库函数在其官网有对应的说明,可登录其网站查阅
SQLite Home Page
其中,introduction列出了常用的几个函数,如果想看更多函数,可查看其函数列表网页List Of SQLite Functions
对于一般想小型开发,仅需掌握如下四个函数即可:
sqlite3_open()
sqlite3_close()
sqlite3_exec()
sqlite3_get_table()
下面对最常用几个函数进行介绍
sqlite3_open()
此函数功能为创建数据库,如果数据库已经创建,则打开数据库,函数原型如下Opening A New Database Connection
filename为数据库的名字,即执行 ./sqlite3 student命令时的student这个值
ppDb为数据库句柄,后续对数据库的所有操作都通过此句柄进行传值。
使用举例:
sqlite3 *ppDb;int ret = sqlite3_open("student.db", &ppDb);if(ret != SQLITE_OK)
{ printf("Open Sqlite3 Failed : %s\n",sqlite3_errmsg(ppDb));
}
sqlite3_close() 此函数功能为关闭数据库,如果sqlite3对象被成功销毁并且所有相关资源都被释放,则对sqlite3_close()的调用返回SQLITE_OK。函数原型如下Closing A Database Connection使用举例
sqlite3 *ppDb;int ret = sqlite3_open("student.db", &ppDb);if(ret != SQLITE_OK)
{ printf("Open Sqlite3 Failed : %s\n",sqlite3_errmsg(ppDb));
}ret = sqlite3_close(ppDb); //关闭数据库if(ret != SQLITE_OK)
{ printf("Release Sqlite3 Failed : %s\n",sqlite3_errmsg(ppDb));
}
sqlite3_exec()
此函数为sqlite3函数的重中之重,用它可以执行几乎所有的sqlite3命令。函数原型如下One-Step Query Execution Interface
第一个参数 sqlite3*,为一个打开的数据库的句柄,比如前面sqlite3_open函数中ppDb参数。
第二个参数为填有sql的命令行语句的字符串
第三个参数为回调函数。回调函数返回值为 int。但此参数只对有显示的命令行有效,比如:select * from student命令
第四个参数为回调函数需要传入的参数,即回调函数的第一个参数值
第五个保存错误消息
使用举例一
#include <stdio.h>
#include <stdlib.h>
#include "sqlite3.h"int main(void)
{//打开或者创建数据库文件sqlite3 *ppdb;int ret = sqlite3_open("student.db",&ppdb);if(ret != SQLITE_OK){printf("Open Sqlite Failed -- %s\n",sqlite3_errmsg(ppdb));exit(1);}//创建数据表char *sqltCmd = "create table student (id integer, name txt, age integer);";ret = sqlite3_exec(ppdb, sqltCmd, NULL, NULL, NULL);if(ret != SQLITE_OK){printf("sqlite3_exec1 Failed! -- %s\n", sqlite3_errmsg(ppdb));exit (1);}//再次创建数据表char *errmsg;ret = sqlite3_exec(ppdb, sqltCmd, NULL, NULL, &errmsg); //第五个参数保存错误消息if(ret != SQLITE_OK){//因为sqltCmd中的命令重复创建了数据表,所以会报错,命令行中的错误会通过errmsg指针返回//可以通过命令行输入两遍 sqltCmd 命令对比程序运行中的下一行打印printf("sqlite3_exec1 Failed! -- %s\n", sqlite3_errmsg(ppdb));exit (1);}ret = sqlite3_close(ppdb);if(ret != SQLITE_OK){printf("Sqlite Release Failed -- %s\n",sqlite3_errmsg(ppdb));exit(1);}return 0;
}
使用举例二
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"/*
print函数每查询一行,就执行一次,故无需返回数据库的数据条数,也为行数
sql:需要传入的其它参数
colum:返回数据库的字段数,也为列数
value: 返回字段的值
name:返回字段的名称
*/
int print(void * sql, int column, char** value, char ** name)
{printf("第一个参数示例:%s\n",sql);int i;for(i = 0; i < column; i++){printf("%s=%s ", name[i], value[i]);}printf("\n");return 0;
}int main(void)
{//创建或打开数据库sqlite3 *ppdb;int ret = sqlite3_open("student.db", &ppdb);if(ret != SQLITE_OK){printf("sqlite3_open : %s\n", sqlite3_errmsg(ppdb));exit(1);}//创建表 studentchar* sql = "create table if not exists student (id integer, name txt, age integer);";ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);if(ret != SQLITE_OK){printf("sqlite3_exec1 : %s\n", sqlite3_errmsg(ppdb));exit(1);}char cmd[256] = {0};int id, age, i;char name[256]={0};for(i = 0; i < 2; i++){printf("请输入学号、名字和年龄:\n");scanf("%d%s%d",&id,name,&age);memset(cmd, 0, sizeof(cmd));sprintf(cmd,"insert into student (id, name, age) values(%d, '%s', %d);",id,name,age);ret = sqlite3_exec(ppdb, cmd, NULL, NULL, NULL);if(ret != SQLITE_OK){printf("sqlite3_exec2 : %s\n", sqlite3_errmsg(ppdb));exit(1);}}memset(cmd, 0, sizeof(cmd));sprintf(cmd,"select * from student;");ret = sqlite3_exec(ppdb, cmd, print, sql, NULL);//此处sql仅仅是用来说明传参问题if(ret != SQLITE_OK){printf("sqlite3_exec3 : %s\n", sqlite3_errmsg(ppdb));exit(1);}ret = sqlite3_close(ppdb);if(ret != SQLITE_OK){printf("sqlite3_close : %s\n", sqlite3_errmsg(ppdb));exit(1);}return 0;
}
执行效果如下
sqlite3_exec函数回调参数的再说明
以 使用举例二 为例,假如此时数据表中含有4项数据
在调用sqlite3_exec函数查询数据表时
每查询到一条数据,则调用一次 回调函数 print。
假如现在查询完第一条数据,即 1|aa|11
则返回列数为 3(形参column 为 3),数据值为 1 aa 11 的字符串(即 *value 指向{"1", "aa", "11"}的字符串首地址),字段值为 id name age 的字符串(即*name 指向{"id","name","age"}的字符串的首地址)
因此,可以通过 value[i] 和 name[i] 找到对应的字符串
- sqlite3_get_table
此函数为sqlite3专门用于查询语句的函数,函数原型如下
Convenience Routines For Running Queries
第一个参数为数据库的句柄
第二个参数为填有sql的命令行语句的字符串
第三个参数为查询后的返回值
第四个参数为查询到数据库中数据的条数(即行数)
第五个参数为查询到数据库中数据的字段数(即列数)
第三参数pazResult为一个一维数组,存放方式为 表头,表1对应的值,表2对应的值......
仍然以前面数据库为例说明
pazResult中数据存放方式如下图所述
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlite3.h"int main(void)
{//创建或打开数据库sqlite3* ppdb;int ret = sqlite3_open("student.db",&ppdb);if(ret != SQLITE_OK){printf("sqlite3_open : %s\n", sqlite3_errmsg(ppdb));exit(1);}char* sql = "create table student(id integer, name text, age integer);";ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);if(ret != SQLITE_OK){printf("sqlite3_exec1 : %s\n", sqlite3_errmsg(ppdb));exit(1);}char cmd[256] = {0};int id, age, i, j;char name[128] = {0};for(i = 0; i < 2; i++){printf("请输入学号、名字和年龄:\n");scanf("%d%s%d",&id, name, &age);memset(cmd, 0, sizeof(cmd));sprintf(cmd, "insert into student(id, name, age) values (%d, '%s', %d);",id,name,age);ret = sqlite3_exec(ppdb, cmd, NULL, NULL, NULL);if(ret != SQLITE_OK){printf("sqlite3_exec2 : %s\n", sqlite3_errmsg(ppdb));exit(1);}}char **result;int row, column;memset(cmd, 0, sizeof(cmd));sprintf(cmd, "select * from student;");ret = sqlite3_get_table(ppdb, cmd, &result, &row, &column, NULL);if(ret != SQLITE_OK){printf("sqlite3_get_table: %s\n", sqlite3_errmsg(ppdb));exit(1);}int Index = column;for(i = 0; i < row; i++){for(j = 0; j < column; j++){//result[j]是指的表头的三个字符串//result[Index]是指的实际数据,实际数据是跨过表头后从column开始的数据//参照上面的内存截图理解printf("%s=%s ",result[j], result[Index]);Index++;}printf("\n");}return 0;
}
实际执行效果如图