参考文章:玩转SQLite-11:C语言高效API之sqlite3_prepare系列函数 - 知乎 (zhihu.com)
sqlite3错误码:
#define SQLITE_OK 0 /* 成功 */
/* 错误码 */
#define SQLITE_ERROR 1 /* sql错误或丢失的数据库,SQL error or missing database */
#define SQLITE_INTERNAL 2 /* sqlite内部逻辑错误,Internal logic error in SQLite */
#define SQLITE_PERM 3 /* 拒绝访问,Access permission denied */
#define SQLITE_ABORT 4 /* 回调函数请求取消操作,Callback routine requested an abort */
#define SQLITE_BUSY 5 /* 数据库文件被锁定,The database file is locked */
#define SQLITE_LOCKED 6 /* 数据库的一个表被锁定,A table in the database is locked */
#define SQLITE_NOMEM 7 /* 某次malloc函数调用失败,A malloc() failed */
#define SQLITE_READONLY 8 /* 尝试写入一个只读数据库,Attempt to write a readonly database */
#define SQLITE_INTERRUPT 9 /* 操作sqlite3_interrupt函数被中断,Operation terminated by sqlite3_interrupt()*/
#define SQLITE_IOERR 10 /* 发生磁盘I/O错误,Some kind of disk I/O error occurred */
#define SQLITE_CORRUPT 11 /* 数据库磁盘映像不正确,The database disk image is malformed */
#define SQLITE_NOTFOUND 12 /* 找不到表或记录,NOT USED. Table or record not found */
#define SQLITE_FULL 13 /* 数据库满而插入失败,Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* 无法打开数据库,Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* 数据库锁定协议错误,NOT USED. Database lock protocol error */
#define SQLITE_EMPTY 16 /* 数据库为空,Database is empty */
#define SQLITE_SCHEMA 17 /* 数据库结构发生改变,The database schema changed */
#define SQLITE_TOOBIG 18 /* 数据大小超限,String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* 约束违反,Abort due to constraint violation */
#define SQLITE_MISMATCH 20 /* 数据类型不匹配,Data type mismatch */
#define SQLITE_MISUSE 21 /* 库使用不正确,Library used incorrectly */
#define SQLITE_NOLFS 22 /* 使用了操作系统不支持的功能,Uses OS features not supported on host */
#define SQLITE_AUTH 23 /* 授权失败,Authorization denied */
#define SQLITE_FORMAT 24 /* 附加数据库格式错误,Auxiliary database format error */
#define SQLITE_RANGE 25 /* sqlite3_bind的第2给参数超出范围,2nd parameter to sqlite3_bind out of range */
#define SQLITE_NOTADB 26 /* 不是数据库文件,File opened that is not a database file */
#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */
#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */
#define SQLITE_ROW 100 /* sqlite3_step产生一个就绪行,sqlite3_step() has another row ready */
#define SQLITE_DONE 101 /* sqlite3_step执行完成,sqlite3_step() has finished executing */
-
sqlite3_open
:
作用:打开一个 SQLite 数据库连接。 使用方法:int sqlite3_open(const char *filename, sqlite3 **ppDb);
filename
:要打开的数据库文件的名称。ppDb
:指向指向数据库连接对象的指针的指针。- 返回值:若成功打开数据库,则返回
SQLITE_OK
,否则返回错误代码。
-
sqlite3_exec
:
作用:执行 SQL 语句并对结果进行处理。 使用方法:int sqlite3_exec(sqlite3 *db, const char *sql, int (*callback)(void *, int, char **, char **), void *data, char **errmsg);
db
:数据库连接对象。sql
:要执行的 SQL 语句。callback
:结果回调函数,可选。用于处理每一行的查询结果。data
:传递给回调函数的用户数据。errmsg
:如果出现错误,将保存错误信息。- 返回值:若成功执行 SQL 语句,则返回
SQLITE_OK
,否则返回错误代码。
当执行sqlite3_exec时,其内部的执行可分为3步:
- 解析sql语句字符串
- 编译sql语句
- 执行sql语句
sqlite3_exec的功能进行分解,由多个函数共同完成。
- sqlite3_prepare_v2()函数:实现对sql语句(模板)的解析和编译,生成了可以被执行的 sql语句实例
- sqlite3_stmt()数据结构:可以理解为一种“准备语句对象”,它可以结合变量使用,进而实现相同操作的循环
- sqlite3_bind_*() 函数:用于绑定赋值变量
- sqlite3_step() 函数:用于执行sql语句
相比较使用sqlite3_exec函数,现在这种方式,sql语句的解析和编译只执行了一次,而sqlite3_step执行多次,整体的效率势必大大提升。
-
sqlite3_prepare_v2
:(解析和编译SQL语句,产生SQL语句实例)int sqlite3_prepare_v2(sqlite3 *db, const char *sql, int sql_len, sqlite3_stmt **stmt, const char **tail);
作用:编译 SQL 语句,创建一个准备好的语句对象。 使用方法:
db
:数据库连接对象。sql
:要编译的 SQL 语句。sql_len
:SQL 语句的长度,如果为-1,则表示自动计算长度。stmt
:指向准备好的语句对象的指针。tail
:未使用的部分 SQL 语句。- 返回值:若成功编译 SQL 语句,则返回
SQLITE_OK
,否则返回错误代码。
-
sqlite3_step
:int sqlite3_step(sqlite3_stmt *stmt);
作用:执行准备好的语句。 使用方法:
stmt
:准备好的语句对象。- 返回值:若成功执行语句,则返回
SQLITE_ROW
(表示有一行结果)或SQLITE_DONE
(表示执行完毕),若出现错误,则返回错误代码。
-
sqlite3_column_text
:const unsigned char *sqlite3_column_text(sqlite3_stmt *stmt, int col);
作用:获取查询结果集的指定列的文本值。 使用方法:
stmt
:准备好的语句对象。- Col: 要查询的"列"索引值。sqlite3规定最左侧的“列”索引值是 0,也就是“列”索引号从 0 开始。
- 返回值:指向列值的字符串指针。
#include <stdio.h>
#include <sqlite3.h>
int main(char argc, char **argv)
{
if(argc<2){
printf("param miss\n"); // 缺少参数时输出提示信息
}
sqlite3 *db; // SQLite 数据库连接对象
int rc = sqlite3_open(argv[1],&db); // 打开数据库连接
if(rc){
fprintf(stderr,"can not open database:%s, err_num:%d\n",sqlite3_errmsg(db), rc); // 打开数据库失败时输出错误信息
return -1;
}else{
printf("open success\n"); // 打开数据库成功时输出成功信息
}
sqlite3_close(db); // 关闭数据库连接
printf("close_success\n"); // 输出关闭成功信息
return 0;
}
查找mytable这张表的数据
#include <stdio.h>
#include <sqlite3.h>
// 回调函数,用于处理查询结果
int callback(void* para, int columnCount, char** columnValue, char** columnName)
{
// 遍历每一列的值和对应的列名,并打印输出
for (int i = 0; i < columnCount; i++) {
printf("%s: %s\n", columnName[i], columnValue[i]);
}
printf("==================================================\n");
return 0; // 必须返回0
}
int main(char argc, char **argv)
{
if (argc < 2) {
printf("param miss\n");
}
sqlite3* db;
int rc = sqlite3_open(argv[1], &db); // 打开数据库
if (rc) {
fprintf(stderr, "can not open database: %s, err_num: %d\n", sqlite3_errmsg(db), rc);
return -1;
} else {
printf("open success\n");
}
char* errmsg;
char* sql = "select * from mytable"; // SQL查询语句
sqlite3_exec(db, sql, callback, NULL, &errmsg); // 执行查询并调用回调函数处理结果
sqlite3_close(db); // 关闭数据库
printf("close success\n");
return 0;
}
在创建的表内插入、更新、查找数据
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
// 回调函数,用于处理查询结果
int callback(void* para, int columnCount, char** columnValue, char** columnName)
{
// 遍历每一列的值和对应的列名,然后打印出来
for (int i = 0; i < columnCount; i++) {
printf("%s: %s\n", columnName[i], columnValue[i]);
}
printf("==================================================\n");
return 0; // 必须返回0,表示继续执行下一次回调
}
int main(char argc, char **argv)
{
if (argc < 2) {
printf("param miss\n");
}
sqlite3* db;
int rc = sqlite3_open(argv[1], &db); // 打开数据库
if (rc) {
fprintf(stderr, "can not open database: %s, err_num: %d\n", sqlite3_errmsg(db), rc);
return -1;
} else {
printf("open success\n");
}
char* errmsg;
char* sql = "select * from class"; // SQL查询语句
char *sql1 = "create table class(ID Integer ,name text,score Integer)"; // 创建表
char *sql2 = "pragma table_info(class)"; // 查询表的参数
char *sql3 = "insert into class values(01,'张三',100);" // 插入数据
"insert into class values(02,'李四',99);"
"insert into class values(03,'王五',98);"
"insert into class values(04,'bby',59);";
char *sql4 = "alter table class add column sex test;" // 更新表的参数
"pragma table_info(class);"
"update class set sex ='男' where ID = 1;"
"update class set sex ='女' where ID = 2;"
"update class set sex ='女' where ID = 3;";
int ret;
ret = sqlite3_exec(db, sql1, callback, NULL, &errmsg); // 执行SQL语句,创建表
if (ret != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errmsg);
sqlite3_free(errmsg); // 释放错误信息字符串
} else {
fprintf(stdout, "Table created successfully\n");
}
ret = sqlite3_exec(db, sql2, callback, NULL, &errmsg); // 执行SQL语句,查询表的参数
if (ret != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errmsg);
sqlite3_free(errmsg);
} else {
fprintf(stdout, "Table check pragma successfully\n");
}
ret = sqlite3_exec(db, sql3, callback, NULL, &errmsg); // 执行SQL语句,插入数据
if (ret != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errmsg);
sqlite3_free(errmsg);
} else {
fprintf(stdout, "Table insert data successfully\n");
}
ret = sqlite3_exec(db, sql, callback, NULL, &errmsg); // 执行SQL查询语句,并调用回调函数处理结果
if (ret != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errmsg);
sqlite3_free(errmsg);
} else {
fprintf(stdout, "Table view data successfully\n");
}
printf("=================================================================================updata===================================================================================================\n");
ret = sqlite3_exec(db, sql4, callback, NULL, &errmsg); // 执行SQL语句,更新表的参数
if (ret != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errmsg);
sqlite3_free(errmsg);
} else {
fprintf(stdout, "Table alter data successfully\n");
}
ret = sqlite3_exec(db, sql, callback, NULL, &errmsg); // 执行SQL查询语句,并调用回调函数处理结果
if (ret != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", errmsg);
sqlite3_free(errmsg);
} else {
fprintf(stdout, "Table view data successfully\n");
}
sqlite3_close(db); // 关闭数据库连接
printf("close success\n");
return 0;
}
sql语句可以是多条语句的组合,中间用’;‘分开即可。
20230926