Linux下利用c/c++使用sqlite

简介: Linux下利用c/c++使用sqlite

参考链接:

https://blog.csdn.net/u012351051/article/details/90382391

https://blog.csdn.net/no_sying_nothing/article/details/52518822

https://cloud.tencent.com/developer/article/1018696

1. 安装sqlite

0> 下载 wget https://www.sqlite.org/2021/sqlite-autoconf-3360000.tar.gz

1> 解压

2>./configure --prefix=/home/sqlite3_lib

3> make

4> make install

可以看到/home/sqlite3_lib目录下已经安装了需要的库和头文件,我们直接拷贝在工程里面即可。

2. sqlite常用的三个操作API

1. 1、sqlite3_open(const char* filename, sqlite3 **ppDb);
2. 
3. 2、int sqlite3_exec(
4.        sqlite3*,                                  /* An open database */
5.        const char *sql,                           /* SQL to be evaluated */
6.        int (*callback)(void*,int,char**,char**),  /* Callback function */
7.        void *,                                    /* 1st argument to callback */
8.        char **errmsg                              /* Error msg written here */
9.     );
10. 
11. sqlite3*            : open 打开的数据库
12. const char* sql,    : 执行的sql功能语句
13. *callback,          : sql语句对应的回调函数
14. void* data,         : 传递给回调函数的 指针参数
15. char **errmsq       : 错误信息
16. 
17. 3、sqlite3_close(sqlite3*)

3. sqlite3_exec的回调函数 callback

1. typedef int(*sqlite_callback)(void* para, int columenCount, char** columnValue, char** columnName);
2. 
3. 参数:
4. para : 由sqlite3_exec传入的参数指针【第四个参数】,或者说是指针参数 
5. columnCount: 查询到的这一条记录由多少个字段(多少列)
6. columnValue  : 该参数是双指针,查询出来的数据都保存在这里,它是一个1维数组,每一个元素都是一
7.                     个char*,是一个字段内容,所以这个参数就可以不是单字节,而是可以为字符串等不定
8.                     长度的数值,用字符串表示,以'\0'结尾。        
9. columnName : 该参数是双指针,语columnValue是对应的,表示这个字段的字段名称,
10. 
11. 返回      : 执行成果则返回SQLITE_OK,否则返回其他值                  
12.

  这里面有几个地方容易理解错,回调函数的参数一定是 sql功能命令执行结果的进一步处理,其中para好理解,就是sqlite3_exec传递的参数,

  columnCount:表示sql功能结果的“字段”,也就是“列”的个数,没错,就是“列”的个数。

  另外需要特别注意的是:回调函数多数时候不是执行1次,而是会循环执行n次,当我们使用select进行sql功能时,往往输出的结果会是 多行,那么 有n行,就会执行n次的 回调函数。举例如下:

 

1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <sqlite3.h>
4. 
5. static int callback(void *data, int argc, char **argv, char **azColName){
6.    int i;
7.    fprintf(stderr, "%s: ", (const char*)data);
8. for(i=0; i<argc; i++){
9.       printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
10.    }
11.    printf("\n");
12. return 0;
13. }
14. 
15. int main(int argc, char* argv[])
16. {
17.    sqlite3 *db;
18.    char *zErrMsg = 0;
19.    int rc;
20.    char *sql;
21.    const char* data = "Callback function called";
22. 
23. /* Open database */
24.    rc = sqlite3_open("test.db", &db);
25. if( rc ){
26.       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
27. exit(0);
28.    }else{
29.       fprintf(stderr, "Opened database successfully\n");
30.    }
31. 
32. /* Create SQL statement */
33.    sql = "SELECT * from COMPANY";
34. 
35. /* Execute SQL statement */
36.    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
37. if( rc != SQLITE_OK ){
38.       fprintf(stderr, "SQL error: %s\n", zErrMsg);
39.       sqlite3_free(zErrMsg);
40.    }else{
41.       fprintf(stdout, "Operation done successfully\n");
42.    }
43.    sqlite3_close(db);
44. return 0;
45. }

这个数据库中表的内容如下(这里照搬了https://www.runoob.com/sqlite/sqlite-c-cpp.html 中的例子):

1. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
2. "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
3. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
4. "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
5. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
6. "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
7. "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
8. "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

所以执行的结果:

1. Opened database successfully
2. Callback function called: ID = 1
3. NAME = Paul
4. AGE = 32
5. ADDRESS = California
6. SALARY = 20000.0
7. 
8. Callback function called: ID = 2
9. NAME = Allen
10. AGE = 25
11. ADDRESS = Texas
12. SALARY = 15000.0
13. 
14. Callback function called: ID = 3
15. NAME = Teddy
16. AGE = 23
17. ADDRESS = Norway
18. SALARY = 20000.0
19. 
20. Callback function called: ID = 4
21. NAME = Mark
22. AGE = 25
23. ADDRESS = Rich-Mond
24. SALARY = 65000.0
25. 
26. Operation done successfully

  可以看出来,由于sql命令行为 select* from COMPANY,该命令会将表中所有信息都输出,总共5个字段(列),包含4条信息(行),所以这个回调函数会被执行4次,理解这个逻辑,非常重要。

 而且回调函数的后两个参数是 双指针 ,也就是 指针的指针,包含了2层的指向,里层的 指向是 对应具体的数据指针,外层的指向则是  数据指针序号,也可以理解成 “列”索引。我们通过这两个指针能够进一步 编写 自定义功能代码。

 

4. 打开数据库并创建表

1. #include<stdio.h>
2. #include<sqlite3.h>
3. 
4. // 暂时先不管
5. static int callback(void *NotUsed, int argc, char **argv, char **azColName)
6. {
7.     int i = 0;
8. for(i = 0; i < argc; i++)
9.     {
10.         printf("%s = %s\n",azColName[i], argv[i]?argv[i]:"NULL");
11.     }
12. 
13.     printf("\n");
14. return 0;
15. }
16. 
17. int main()
18. {
19.     sqlite3* db;
20.     char *zErrMsg = 0;
21.     int rc;
22.     char *sql;
23. 
24.     rc = sqlite3_open("test.db", &db);  // 打开数据库
25. if(rc)
26.     {
27.         fprintf(stderr, "Can't open database:%s\n", sqlite3_errmsg(db));
28. //        exit(0);
29. return -1;
30.     }
31. else
32.     {
33.         fprintf(stderr,"open database succeddfully\n");
34.     }
35. 
36.     sql = "create table company(ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE TEXT NOT NULL, ADDRESS CHAR(50))";
37. 
38.     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); // 执行上面sql中的命令
39. if(SQLITE_OK != rc)
40.     {
41.         fprintf(stderr, "SQL error: %s\n", zErrMsg);
42.     }
43. else
44.     {
45.         fprintf(stdout, "create table successfully\n");
46.     }
47. 
48.     sqlite3_close(db);
49. return 0;
50. }

运行:需要链接sqlite3库,下面的其他操作也是如此。

gcc sqlite3test.c -o create -l sqlite3

5. 插入数据

sql语法:

insert into + 表名 (列1, 列2, ...,列n)values(对应每列的值)

1. #include<stdio.h>
2. #include<sqlite3.h>
3. 
4. static int callback(void *NotUsed, int argc, char **argv, char **azColName)
5. {
6.     int i = 0;
7. for(i = 0; i < argc; i++)
8.     {
9.         printf("%s = %s\n",azColName[i], argv[i]?argv[i]:"NULL");
10.     }
11. 
12.     printf("\n");
13. return 0;
14. }
15. 
16. int main()
17. {
18.     sqlite3* db;
19.     char *zErrMsg = 0;
20.     int rc;
21.     char *sql;
22. 
23.     rc = sqlite3_open("test.db", &db);
24. if(rc)
25.     {
26.         fprintf(stderr, "Can't open database:%s\n", sqlite3_errmsg(db));
27. //        exit(0);
28. return -1;
29.     }
30. else
31.     {
32.         fprintf(stderr,"open database succeddfully\n");
33.     }
34. 
35. //    sql = "create table company(ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE TEXT NOT NULL, ADDRESS CHAR(50))";
36. 
37.     sql = "insert into company(ID, NAME, AGE, ADDRESS) values(1, 'Paul', 25, 'USA');\
38.         insert into company(ID, NAME, AGE, ADDRESS) values(2, 'James', 28, 'JAP');\
39.         insert into company(ID, NAME, AGE, ADDRESS) values(3, 'Yao', 30, 'CHA');\
40.         insert into company(ID, NAME, AGE, ADDRESS) values(4, 'kobe', 38, 'USA');";
41. 
42.     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
43. if(SQLITE_OK != rc)
44.     {
45.         fprintf(stderr, "SQL error: %s\n", zErrMsg);
46.     }
47. else
48.     {
49.         fprintf(stdout, "insert table successfully\n");
50.     }
51. 
52.     sqlite3_close(db);
53. return 0;
54. }

6. 查询数据:

1. #include<stdio.h>
2. #include<sqlite3.h>
3. 
4. static int callback(void *NotUsed, int argc, char **argv, char **azColName)
5. {
6.     int i = 0;
7. for(i = 0; i < argc; i++)
8.     {
9.         printf("%s = %s\n",azColName[i], argv[i]?argv[i]:"NULL");
10.     }
11. 
12.     printf("\n");
13. return 0;
14. }
15. 
16. int main()
17. {
18.     sqlite3* db;
19.     char *zErrMsg = 0;
20.     int rc;
21.     char *sql;
22. 
23.     rc = sqlite3_open("test.db", &db);
24. if(rc)
25.     {
26.         fprintf(stderr, "Can't open database:%s\n", sqlite3_errmsg(db));
27. //        exit(0);
28. return -1;
29.     }
30. else
31.     {
32.         fprintf(stderr,"open database succeddfully\n");
33.     }
34. 
35.     sql = "select * from  company;";
36. 
37.     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
38. if(SQLITE_OK != rc)
39.     {
40.         fprintf(stderr, "SQL error: %s\n", zErrMsg);
41.     }
42. else
43.     {
44.         fprintf(stdout, "select table successfully\n");
45.     }
46. 
47.     sqlite3_close(db);
48. return 0;
49. }

请看输出:

7. 更新并查询

1. #include<stdio.h>
2. #include<sqlite3.h>
3. 
4. static int callback(void *NotUsed, int argc, char **argv, char **azColName)
5. {
6.     int i = 0;
7. for(i = 0; i < argc; i++)
8.     {
9.         printf("%s = %s\n",azColName[i], argv[i]?argv[i]:"NULL");
10.     }
11. 
12.     printf("\n");
13. return 0;
14. }
15. 
16. int main()
17. {
18.     sqlite3* db;
19.     char *zErrMsg = 0;
20.     int rc;
21.     char *sql;
22. 
23.     rc = sqlite3_open("test.db", &db);
24. if(rc)
25.     {
26.         fprintf(stderr, "Can't open database:%s\n", sqlite3_errmsg(db));
27. //        exit(0);
28. return -1;
29.     }
30. else
31.     {
32.         fprintf(stderr,"open database succeddfully\n");
33.     }
34. 
35.     sql = "update  company set ADDRESS = 'RUS' where ID = 3;\
36.         select * from company;";
37. 
38.     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
39. if(SQLITE_OK != rc)
40.     {
41.         fprintf(stderr, "SQL error: %s\n", zErrMsg);
42.     }
43. else
44.     {
45.         fprintf(stdout, "update table successfully\n");
46.     }
47. 
48.     sqlite3_close(db);
49. return 0;
50. }

8. 删除并查询

1. #include<stdio.h>
2. #include<sqlite3.h>
3. 
4. static int callback(void *NotUsed, int argc, char **argv, char **azColName)
5. {
6.     int i = 0;
7. for(i = 0; i < argc; i++)
8.     {
9.         printf("%s = %s\n",azColName[i], argv[i]?argv[i]:"NULL");
10.     }
11. 
12.     printf("\n");
13. return 0;
14. }
15. 
16. int main()
17. {
18.     sqlite3* db;
19.     char *zErrMsg = 0;
20.     int rc;
21.     char *sql;
22. 
23.     rc = sqlite3_open("test.db", &db);
24. if(rc)
25.     {
26.         fprintf(stderr, "Can't open database:%s\n", sqlite3_errmsg(db));
27. //        exit(0);
28. return -1;
29.     }
30. else
31.     {
32.         fprintf(stderr,"open database succeddfully\n");
33.     }
34. 
35.     sql = "delete from company where ID = 2;\
36.         select * from company;";
37. 
38.     rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
39. if(SQLITE_OK != rc)
40.     {
41.         fprintf(stderr, "SQL error: %s\n", zErrMsg);
42.     }
43. else
44.     {
45.         fprintf(stdout, "delete table successfully\n");
46.     }
47. 
48.     sqlite3_close(db);
49. return 0;
50. }


相关文章
|
2月前
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
95 0
|
2月前
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
88 1
Linux C/C++之IO多路复用(aio)
|
2月前
|
资源调度 Linux 调度
Linux c/c++之进程基础
这篇文章主要介绍了Linux下C/C++进程的基本概念、组成、模式、运行和状态,以及如何使用系统调用创建和管理进程。
39 0
|
2月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
344 3
|
2月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
30 0
Linux C/C++之线程基础
|
2月前
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
27 0
Linux C/C++之IO多路复用(poll,epoll)
|
2月前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
40 0
Linux C/C++之TCP / UDP通信
|
2月前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
33 0
Linux c/c++之IPC进程间通信
|
2月前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
30 0
Linux c/c++进程间通信(1)
|
2月前
|
Linux C++
Linux c/c++之进程的创建
这篇文章介绍了在Linux环境下使用C/C++创建进程的三种方式:system函数、fork函数以及exec族函数,并展示了它们的代码示例和运行结果。
40 0
Linux c/c++之进程的创建