如何快速使用C语言操作sqlite3
itopen组织
1、提供OpenHarmony优雅实用的小工具
2、手把手适配riscv + qemu + linux的三方库移植
3、未来计划riscv + qemu + ohos的三方库移植 + 小程序开发
4、一切拥抱开源,拥抱国产化
一、sqlite3库介绍
sqlite3库可从官网下载,当前版本为sqlite3 3.45.3
https://www.sqlite.org/download.html
二、sqlite3编译
2.1 x86_64架构安装
2.1.1 命令安装
sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev
2.1.2 源码编译安装
./configure
make -j$(nproc)
sudo make install
2.2 基于arm架构编译
2.2.1 下载工具链并安装
# 下载工具链
wget https://repo.huaweicloud.com/openharmony/compiler/prebuilts_gcc_linux-x86_arm_gcc-linaro-7.5.0-arm-linux-gnueabi/1.0/prebuilts_gcc_linux-x86_arm_gcc-linaro-7.5.0-arm-linux-gnueabi.tar.gz
tar -xvf prebuilts_gcc_linux-x86_arm_gcc-linaro-7.5.0-arm-linux-gnueabi.tar.gz# 设置工具链的路径
vim ~/.bashrc
# 最后一行添加
export PATH=~/bin/prebuilts_gcc_linux-x86_arm_gcc-linaro-7.5.0-arm-linux-gnueabi/bin:$PATH
# 重置.bashrc
source ~/.bashrc
2.2.2 编译sqlite3
export CC=aarch64-linux-gnu-gcc
./configure --prefix=$PWD/_install CC=aarch64-linux-gnu-gcc --host=aarch64-linux
./configure --prefix=$PWD/_install
make -j$(nproc)
make install
2.3 基于riscv64架构编译
2.3.1 工具链安装
sudo apt-get install gcc-riscv64-linux-gnu
2.3.2 编译sqlite3
./configure --prefix=$PWD/_install CC=riscv64-linux-gnu-gcc --host=riscv64-linux
make -j$(nproc)
make install
三、接口介绍
参考链接:
https://geek-docs.com/sqlite
3.1 打开/创建数据库
int sqlite3_open(const char *filename, sqlite3 **ppDb);
3.2 关闭数据库
int sqlite3_close(sqlite3 *db);
3.3 执行sql语句
int sqlite3_exec(sqlite3*,const char *sql,int (*callback)(void *, int, char **, char **),void *arg,char **errmsg);
3.4 获取结果内容
int sqlite3_get_table(sqlite3 *db,const char *zSql,char ***pazResult,int *pnRow,int *pnColumn,char **pzErrmsg);
3.5 获取错误信息
const char *sqlite3_errmsg(sqlite3 *db);
3.6 释放表空间
void sqlite3_free_table(char **result);
四、sqlite3语句
4.1 sqlite数据类型
NULL:标识一个NULL值
INTEGER(intger):整数类型 int
REAL(real):浮点数 float,double
TEXT(text):字符串 ""
CHAR(char):字符''
4.2 创建表
create if not exists table table_name(column1 type1, column2 type2, column3 type3……);
# 例如创建一个名为dictory的表(sheet),里面有word、translation等字段
create table if not exists table_name(word text, translation text);# not null 指定列不允许为NULL值
create table if not exists student(student_name txt not NULL, id txt not NULL, sex char);# default 在insert into语句没有提供特定的值时,为列提供一个默认值
create table if not exists student(student_name txt not NULL, id txt not NULL, sex char, grade integer default 99);# unique 约束防止一个特定的列存在两个相同的值
create table if not exists student(student_name txt not NULL unique, id txt not NULL, sex char);# check 约束 启用输入一条记录要检查值的条件。如果条件值为false,则记录违反了约束,且不能输入到表
create table if not exists student(student_name txt not NULL, id txt not NULL, sex char, grade intger check(grade > 0));
4.3 添加记录
insert into table_name(column1, column2, column3) values(val1, val2, val3);
insert into student(student_name, id, sex) values ('z3', '123', 'm');
或者
insert into student values('z3', '123', 'm');
4.4 查询
4.4.1 查看表结构
.schema
4.4.2 查看所有表
.tables
4.4.3 查看记录
# 获取所有数据记录
select * from table_name;# 限制输出数据记录数量
select * from table_name limit val;# 升序输出数据记录
select * from table_name order by column asc;
select * from dictory order by word asc;# 降序输出数据记录
select * from table_name order by column desc;
select * from dictory order by word desc;# 条件查询
select * from table_name where expression;
select * from table_name where column in ('val1', 'val2', 'val3');
select * from table_name where column = 'val1' or column = 'val2';
select * from table_name where column between val1 and val2;
select * from people where age>=10 and age <=15;
select name, age from people where age>= 10 and age<=15;
select * from table_name where column like 'xx%' or 'xxx_';
百分号(%)代表零个、一个或者多个数字或字符
下划线(_)代表一个单一数字或字符
4.5 修改数据记录
update table_name set column1=val1, column2=val2 where expression;
update student_info set id=0002, name=hencai where id=0001;
4.6 表中添加字段
alter table <table_name> add column <field> <type>;
alter table stu add column age integer;
4.7 删除数据记录
delete from table_name [where expression];
delete from stu where id=123;
4.8 删除表
drop table table_name;
drop table student;
4.9 删除指定字段
# step1:备份为temp id , name , age , sex
alter table info rename to temp;# step2:创建新表
create table info(id, name, age);#step3:导出到新表
insert into info select id, name, age from temp;
4.10 退出sqlite3
.quit
五、sqlite3库封装
5.1 封装库代码
代码来源 itopen组织: test
sqlite3_lib.c代码
#include "sqlite3_lib.h"struct Sqlite3SyncOps sqlite3Sync[] = {{SQLITE3_SYNC_MODE_FULL, "PRAGMA synchronous = FULL"},{SQLITE3_SYNC_MODE_NORMAL, "PRAGMA synchronous = NORMAL"},{SQLITE3_SYNC_MODE_OFF, "PRAGMA synchronous = OFF"},
};int CreateDatabase(char *dbname, sqlite3 **db)
{int ret = sqlite3_open(dbname, db);if (ret != SQLITE_OK) {printf("sqlite3_open error: %s\n", sqlite3_errmsg(*db));return -1;}return SQLITE_OK;
}int SetDatabaseSync(sqlite3 *db, enum Sqlite3SyncMode mode)
{char *errmsg = NULL;if (db == NULL) {printf("db is NULL\n");return -1;}if (sqlite3_exec(db, sqlite3Sync[mode].sql, NULL, NULL, &errmsg)) {printf("sqlite3_exec error: %s\n", errmsg);sqlite3_free(errmsg);return -1;}return SQLITE_OK;
}int CreateDataSheet(sqlite3 *db, const char *sql)
{char *errmsg = NULL;if (db == NULL) {printf("db is NULL\n");return -1;}if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {printf("sqlite3_exec error: %s\n", errmsg);sqlite3_free(errmsg);return -1;}return SQLITE_OK;
}int InsertDataValue(sqlite3 *db, const char *sheet, const char *column, const char *value)
{int i;char sql[1024];char *errmsg = NULL;if (db == NULL) {printf("db is NULL\n");return -1;}sprintf(sql, "insert into %s(%s) values (%s);", sheet, column, value);printf("sql: %s\n", sql);if (sqlite3_exec(db, sql, NULL, NULL, &errmsg)) {printf("sqlite3_exec error: %s\n", errmsg);sqlite3_free(errmsg);return -1;}return SQLITE_OK;
}int CloseDatabase(sqlite3 *db)
{if (db == NULL) {return 0;}return sqlite3_close(db);
}
sqlite3_lib.h代码
#ifndef __SQLITE3_LIB_H__
#define __SQLITE3_LIB_H__#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>enum Sqlite3SyncMode {// 在每次写入操作完成之前,会等待数据被写入磁盘后再继续下一步操作。这种模式具有最高的数据完整性和可靠性,但性能会受到一定影响SQLITE3_SYNC_MODE_FULL = 0,// 在写入操作完成之后,会等待数据被写入磁盘的操作系统缓存中后再继续下一步操作。这种模式在数据完整性和性能之间达到了一种平衡,适用于大多数场景SQLITE3_SYNC_MODE_NORMAL,// 在写入操作完成后,不会等待数据被写入磁盘,直接继续下一步操作。这种模式具有最高的性能,但数据的完整性和可靠性可能会受到一定影响。适用于对数据完整性要求不高的场景,例如缓存数据SQLITE3_SYNC_MODE_OFF
};struct Sqlite3SyncOps {int id;char *sql;
};int CreateDatabase(char *dbname, sqlite3 **db);
int SetDatabaseSync(sqlite3 *db, enum Sqlite3SyncMode mode);
int CreateDataSheet(sqlite3 *db, const char *sql);
int InsertDataValue(sqlite3 *db, const char *sheet, const char *column, const char *value);
int CloseDatabase(sqlite3 *db);#endif /* end of __SQLITE3_LIB_H__ */
Makefile代码
#************************************************************************
#> File Name: Makefile.c
#> Author: Wenfei6316
#> Mail: wen_fei@hoperun.com
#> Created Time: 2024年07月1日 星期一 03时44分36秒
#************************************************************************sqlite3_lib:
gcc sqlite3_lib.c -fPIC -shared -o libsqlite3_lib.so
all: sqlite3_lib ECHOgcc main.c -o main -lsqlite3 -L./ -lsqlite3_libECHO:
@echo $(SUBDIR)@echo "========>begin compile" clean:find ./ -name "*.o" -exec rm {} \;
六、Demo样例
6.1 dictory创建
#include "sqlite3_lib.h"#define CREATE_TABLE "create table if not exists dict(word text primary key, translation text);"int main(int argc, char **argv)
{int i;int cnt = 1;int ret;FILE *fp = NULL;sqlite3 *db = NULL;char buf[1024] = {0};char value[1024] = {0};printf("start create database\n");// 1. 创建数据库ret = CreateDatabase("dictionary.db", &db);if (ret != SQLITE_OK) {printf("CreateDatabase error: %s\n", sqlite3_errmsg(db));return -1;}// 2. 设置数据库同步模式ret = SetDatabaseSync(db, SQLITE3_SYNC_MODE_FULL);if (ret != SQLITE_OK) {printf("SetDatabaseSync error: %s\n", sqlite3_errmsg(db));return -1;}// 3. 常见表格ret = CreateDataSheet(db, CREATE_TABLE);if (ret != SQLITE_OK) {printf("CreateDataSheet error: %s\n", sqlite3_errmsg(db));return -1;}// 4. 插入数据fp = fopen("dict.txt", "r");if (fp == NULL) {printf("open dict.txt error\n");return -1;}while (fgets(buf, sizeof(buf), fp) != NULL) {if (buf[strlen(buf)-1] == '\n') {buf[strlen(buf)-1] = '\0';}// 获取单词结尾地方并设置为\0, 以及翻译起始位置for (i = 0; buf[i] != ' '; i++);buf[i] = '\0';for(; buf[++i] == ' ';);// 插入数据到数据库snprintf(value, 1024, "\"%s\", \"%s\"", &buf[0], &buf[i]);printf("%d: value: %s\n", cnt++, value);ret = InsertDataValue(db, "dict", "word, translation", value);if (ret != SQLITE_OK) {printf("InsertDataValue error: %s\n", sqlite3_errmsg(db));return -1;}memset(buf, '\0', sizeof(buf));memset(value, '\0', sizeof(value));}fclose(fp);CloseDatabase(db);printf("close database success\n");return 0;
}
附录
另有Python简单封装的sqlite3操作可参见 itopen组织: module_code
相关文章:

如何快速使用C语言操作sqlite3
itopen组织1、提供OpenHarmony优雅实用的小工具2、手把手适配riscv qemu linux的三方库移植3、未来计划riscv qemu ohos的三方库移植 小程序开发4、一切拥抱开源,拥抱国产化 一、sqlite3库介绍 sqlite3库可从官网下载,当前版本为sqlite3 3.45.3ht…...

网络模型介绍
网络模型在网络领域中主要指的是用于描述计算机网络系统功能的各种框架,其中最具代表性的两种模型是OSI七层参考模型和TCP/IP四层参考模型。以下是对这两种网络模型的详细解析: 一、OSI七层参考模型 OSI(Open System Interconnection&#…...

Codeforces Round #956 (Div. 2) and ByteRace 2024
A题:Array Divisibility 思路: 大水题 code: inline void solve() {int n; cin >> n;for (int i 1; i < n; i ) {cout << i << " \n"[i n];}return; } B题:Corner Twist 思路࿱…...

域名、网页、HTTP概述
目录 域名 概念 域名空间结构 域名注册 网页 概念 网站 主页 域名 HTTP URL URN URI HTML 超链接 发布 HTML HTML的结构 静态网页 特点 动态网页 特点 Web HTTP HTTP方法 GET方法 POST方法 HTTP状态码 生产环境下常见的HTTP状态码 域名 概念 IP地…...

Redisson分布式锁、可重入锁
介绍Redisson 什么是 Redisson?来自于官网上的描述内容如下! Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格客户端(In-Memory Data Grid)。它不仅提供了一系列的 redis 常用数据结构命令服务,还提供了…...

适合宠物饮水机的光电传感器有哪些
如今,随着越来越多的人选择养宠物,宠物饮水机作为一种便捷的饮水解决方案日益受到欢迎。为了确保宠物随时能够获得足够的水源,宠物饮水机通常配备了先进的光电液位传感器技术。 光电液位传感器在宠物饮水机中起着关键作用,主要用…...

『Python学习笔记』Python运行设置PYTHONPATH环境变量!
Python运行设置PYTHONPATH环境变量! 文章目录 一. Python运行设置PYTHONPATH环境变量!1. 解释2. 为什么有用3. 示例4. vscode配置 一. Python运行设置PYTHONPATH环境变量! export PYTHONPATH$(pwd) 是一个命令,用于将当前目录添…...

2024年06月CCF-GESP编程能力等级认证Python编程三级真题解析
本文收录于专栏《Python等级认证CCF-GESP真题解析》,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(每题 2 分,共 30 分) 第 1 题 小杨父母带他到某培训机构给他报名参加CCF组织的GESP认证…...

代码随想录算法训练营:20/60
非科班学习算法day20 | LeetCode235:二叉搜索树的最近公共祖先 ,Leetcode701:二叉树的插入操作 ,Leetcode450:删除二叉搜索树的节点 介绍 包含LC的两道题目,还有相应概念的补充。 相关图解和更多版本: 代码随想录 (programmer…...

Apache Seata应用侧启动过程剖析——RM TM如何与TC建立连接
本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 Apache Seata应用侧启动过程剖析——RM & TM如何与TC建立连接 前言 看过官网 README 的第…...

Origin 的使用
官网:OriginLab - Origin and OriginPro - Data Analysis and Graphing Software 安装:Origin2022最新最详细的安装教程 学生免费:Origin 官方正版免费续期教程 更改语言:解决OriginPro2024学生版本的更改中文change language灰…...

MySQL相关知识点
目录 1. 基本概念2. 数据类型3. 数据库操作4. 表操作5. 数据操作6. 索引7. 约束8. 事务9. 存储过程和触发器10. 优化和性能调优11. 安全性12. 备份和恢复 MySQL 是一个广泛使用的 关系数据库管理系统 (RDBMS)。了解 MySQL 的主要知识点可以帮助你更好地设计、管理和优化数据库…...

第4章 Vite模块化与插件系统(二)
4.3 常用插件介绍 4.3.1 官方插件 vitejs/plugin-vue 用于支持 Vue.js 开发: npm install vitejs/plugin-vue --save-devimport vue from vitejs/plugin-vueexport default defineConfig({plugins: [vue()] })vitejs/plugin-react 用于支持 React 开发…...

前端传到后端的data数组中有些属性值为空
将前端输入框中的值全部放入data中传入后端,但是在后端查看发现后端接收到的数据有些属性值为空。 第一种情况:只有第一个属性为空,其余属性接收正常 可能原因:后端用来接收的 比如前端发送数据: 实际上前端发送的数…...

怎么批量下载网页里的图片和视频 如何批量下载一个网站的所有图片 如何批量下载网页视频文件 idm软件怎么下载
当我们在网站内需要下载大量图片时,一张一张的下载非常麻烦。这里推荐大家使用IDM这款网页图片下载工具。下面,我将介绍怎么批量下载网页里的图片和视频,如何批量下载一个网站的所有图片的解决方法。 一、怎么批量下载网页里的图片和视频 …...

Python面试题:在 Python 中,如何处理文件操作?
在Python中,文件操作(如读取和写入文件)是一个常见的任务。Python标准库提供了内置的函数和上下文管理器来简化文件操作。以下是处理文件操作的一些基本方法和示例: 打开和关闭文件 使用open()函数打开文件。该函数返回一个文件…...

红日靶机1
靶场环境 使用kali攻击web服务器,然后根据web服务器攻击其他域内的机器 这里很明确kali是攻击机,外网机器,局域网中的win7是web服务器,有2个网卡,通内网和外网,2k3以及2008r2是内网机器,不出网&…...

Windows电脑PC使用adb有线跟无线安装apk包
在Android开发中,经常需要使用ADB(Android Debug Bridge)来安装APK包到Android设备上,无论是通过有线连接还是无线连接。以下将分别介绍如何通过有线和无线方式使用ADB安装APK包。 有线连接安装APK 启用开发者选项和USB调试&…...

如何把harmonos项目修改为openharmony项目
一开始分不清harmonyos和openharmony,在harmonyos直接下载的开发软件,后面发现不对劲,打脑阔 首先你要安装对应版本的开发软件,鸿蒙开发是由harmonyos和openharmony官网两个的,找到对应的地方下载对应版本的开发软件&…...

【QT】Qt智能指针QPointer、QSharedPointer、QWeakPointer、QScopedPointer
QPointer QPointer can only point to QObject instances. It will be automatically set to nullptr if the pointed to object is destroyed. It is a weak pointer specialized for QObject. QPointer只能指向QObject实例。如果指向的对象被销毁,它将自动设置为 …...

设计模式探索:建造者模式
1. 什么是建造者模式 建造者模式 (Builder Pattern),也被称为生成器模式,是一种创建型设计模式。 定义:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 建造者模式要解决的问题: 建造者模…...

[Go] 字符串遍历数据类型问题
字符串遍历问题 在使用for i,v:range str遍历字符串时 str[i]是unit8(byte)类型,返回的是单个字节 字符串在Go中是以字节序列的形式存储的,而 str[i] 直接访问了这个字节序列中的第 i 个字节。如果字符串中的字符是单字节的ASCII…...

HJ41 称砝码
HJ41 称砝码 提示:文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问: 本文目标: 一、背景 这个题目之前是没有做出来的,我把之前没做出来的代码也记录一下 二、 2.1 之前的代码 #include <stdio.h>int m…...

如何使用Python脚本实现SSH登录
调试IDE:PyCharm Python库:Paramiko 首先安装Paramiko包到PyCharm,具体步骤为:在打开的PyCharm工具中,选择顶部菜单栏中“File”下的“Settings”,在设置对话框中,选择“Project”下的“Proje…...

2024年文化研究与数字媒体国际会议 (CRDM 2024)
2024年文化研究与数字媒体国际会议 (CRDM 2024) 2024 International Conference on Cultural Research and Digital Media 【重要信息】 大会地点:珠海 大会官网:http://www.iccrdm.com 投稿邮箱:iccrdmsub-conf.com 【注意:稿将…...

14-52 剑和诗人26 - RAG 和 VectorDB 简介
检索增强生成 (RAG) 和 VectorDB 是自然语言处理 (NLP) 中的两个重要概念,它们正在突破 AI 系统所能实现的界限。 在这篇博文中,我将深入探讨 RAG,探索其工作原理、应用、优势和局限性。 我们还将研究 VectorDB,这是一种专用于向…...

如果MySQL出现 “Too many connections“ 错误,该如何解决?
当你想要连接MySQL时出现"Too many connections" 报错的情况下,该如何解决才能如愿以偿呢?都是哥们儿,就教你两招吧! 1.不想重启数据库的情况下 你可以尝试采取以下方法来解决: 增加连接数限制:…...

论文阅读:Rethinking Interpretability in the Era of Large Language Models
Rethinking Interpretability in the Era of Large Language Models 《Rethinking Interpretability in the Era of Large Language Models》由Chandan Singh、Jeevana Priya Inala、Michel Galley、Rich Caruana和Jianfeng Gao撰写,探讨了在大型语言模型ÿ…...

C++/Qt 信号槽机制详解
文章目录 C++/Qt 信号槽机制详解一、信号和槽的基本概念1. 信号2. 槽3. 连接二、信号和槽的基本使用1. 信号和槽的声明和定义2. 连接信号和槽三、信号和槽的工作原理1. MOC(Meta-Object Compiler)2. 事件循环3. 连接类型四、信号和槽的高级应用1. 自定义信号和槽2. Lambda 表…...

duplicate key value violates unique constraint
duplicate key value violates unique constraint 遇到的问题 你在尝试向数据库表 goods 插入新记录时,收到了 duplicate key value violates unique constraint 的错误。尽管你确认数据库中没有与尝试插入的 id 相同的记录,但错误依旧存在。进一步的调…...