参考链接:
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. }