如何快速使用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实例。如果指向的对象被销毁,它将自动设置为 …...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
leetcode_69.x的平方根
题目如下 : 看到题 ,我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历,我们是整数的平方根,所以我们分两…...
RFID推动新能源汽车零部件生产系统管理应用案例
RFID推动新能源汽车零部件生产系统管理应用案例 一、项目背景 新能源汽车零部件场景 在新能源汽车零部件生产领域,电子冷却水泵等关键部件的装配溯源需求日益增长。传统 RFID 溯源方案采用 “网关 RFID 读写头” 模式,存在单点位单独头溯源、网关布线…...
Unity-ECS详解
今天我们来了解Unity最先进的技术——ECS架构(EntityComponentSystem)。 Unity官方下有源码,我们下载源码后来学习。 ECS 与OOP(Object-Oriented Programming)对应,ECS是一种完全不同的编程范式与数据架构…...
SDU棋界精灵——硬件程序ESP32实现opus编码
一、 音频处理框架 该项目基于Espressif的音频处理框架构建,核心组件包括 ESP-ADF 和 ESP-SR,以下是完整的音频处理框架实现细节: 1.核心组件 (1) 音频前端处理 (AFE - Audio Front-End) main/components/audio_pipeline/afe_processor.c功能: 声学回声…...
Flask和Django,你怎么选?
Flask 和 Django 是 Python 两大最流行的 Web 框架,但它们的设计哲学、目标和适用场景有显著区别。以下是详细的对比: 核心区别:哲学与定位 Django: 定位: "全栈式" Web 框架。奉行"开箱即用"的理念。 哲学: "包含…...
