如何快速使用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 指定列不允许为NULLcreate table if not exists student(student_name txt not NULL, id txt not NULL, sex char);

# defaultinsert 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 ECHO
    gcc main.c -o main -lsqlite3 -L./ -lsqlite3_lib

ECHO:
    @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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/768873.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Http 实现请求body体和响应body体的双向压缩方案

目录 一、前言 二、方案一(和http header不进行关联) 二、方案二(和http header进行关联) 三、 客户端支持Accept-Encoding压缩方式,服务器就一定会进行压缩吗? 四、参考 一、前言 有时请求和响应的body体比较大,需要进行压缩,以减少传输的带宽。 二、方案一(和…

助力构建新型电力系统自主可控实时底座

近日&#xff0c;2024亚洲新型电力系统及储能展览会&#xff06;亚洲新型电力及储能论坛会在广州广交会展馆圆满落下帷幕&#xff01;科东软件携多款电力产品亮相展会,并在2024亚洲新型电力及储能论坛发表《“鸿道Intewell操作系统助力构建新型电力系统自主可控实时底座”》的主…

Unity之创建与导出PDF

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之创建与导出PDF TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01; 助力快速…

2024-2025年本田维修电路图线路图接线图资料更新

此次更新了2024-2025年本田车系电路图资料&#xff0c;覆盖市面上99%车型&#xff0c;包括维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表位置等等&#xff01; 汽修帮手汽…

日期和时区

日期 时区 修改时区可分为两步 删除系统自带的 localtime 文件 rm -f /etc/localtime 将系统中内置的 Shanghai 文件软连接到 /etc/localtime中 sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

Unity3D中,AI角色Rigidbody旋转导致的动画问题

在制作一些AI角色的时候&#xff0c;可能会运用到Rigidbody组件来使AI角色拥有一些相关的物理属性&#xff0c;但是AI角色在受到一些物理碰撞或者惯性等原因&#xff0c;会发生旋转导致动画出现意料外的错误&#xff0c;比如在由动转静的时候&#xff0c;可能会发生向前翻转等一…

TP8/6 子域名绑定应用

原www.xxx.com/admin改为admincms.xxx.com config/app.php

【Linux】线程——线程的概念、线程的特点、线程的优点和缺点、线程和进程、线程函数的使用

文章目录 Linux线程1. 线程的概念1.1 什么是线程 2. 线程的特点2.1 线程的优点2.2 线程的缺点2.4 线程和进程 3. 线程函数的使用pthread_create() 创建线程pthread_self() 获取线程IDpthread_exit() 线程终止pthread_cancel() 线程取消pthread_join() 线程等待pthread_detach()…

Element-UI - el-table中自定义图片悬浮弹框 - 位置优化

该篇为前一篇“Element-UI - 解决el-table中图片悬浮被遮挡问题”的优化升级部分&#xff0c;解决当图片位于页面底部时&#xff0c;显示不全问题优化。 Vue.directive钩子函数已在上一篇中详细介绍&#xff0c;不清楚的朋友可以翻看上一篇&#xff0c; “Element-UI - 解决el-…

3.js - 色调映射(renderer.toneMapping)

// ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import * as TWEEN…

不同操作系统下的换行符

1. 关键字2. 换行符的比较3. ASCII码4. 修改换行符 4.1. VSCode 5. 参考文档 1. 关键字 CR LF CRLF 换行符 2. 换行符的比较 英文全称英文缩写中文含义转义字符ASCII码值操作系统Carriage ReturnCR回车\r13MacIntosh&#xff08;早期的Mac&#xff09;LinefeedLF换行/新行\…

Windows下载安装配置并使用Redis(保姆级教程)

文章目录 1、Redis的下载与安装 2、Redis的使用 3、Redis的图形界面客户端 4、Redis开机自启动 1、Redis的下载与安装 下载Redis&#xff1a;https://pan.baidu.com/s/1zBonkO2y6AZeqCdRe0W5ow?pwd9999 提取码: 9999 下载后直接解压就可以使用了 2、Redis的使用 我们…

全网最佳硕士研究生复试简历模板

硕士研究生复试简历模板 ✨ 简介 提供了一个适用于国内硕士研究生复试的个人简历模板。该模板通过统一的“样式”形成规范的Word格式&#xff0c;是目前研究生复试的最佳简历模板之一。模板使用“华文中宋”字体&#xff0c;如您的电脑中未安装此字体&#xff0c;请提前安装。…

软件测试与质量保证 | 云班课选择题库

目录 第1章课后习题 第2章课后习题 第3章课后习题 第4章课后习题 第5章课后习题 第6章课后习题 第7章课后习题 第8章课后习题 第9章课后习题 第10章课后习题 第11章课后习题 第12章课后习题 第13章 测试相关未分类习题 第1章课后习题 1. 与质量相关的概念包括 &a…

去中心化革命:探索区块链技术的前沿

随着信息技术的飞速发展&#xff0c;区块链技术作为一种新兴的去中心化解决方案&#xff0c;正逐渐改变着我们的经济、社会和技术格局。本文将从区块链的基本原理、当前的应用实例以及未来的发展趋势三个方面&#xff0c;深入探讨区块链技术在革命性变革中的角色和影响。 1. 区…

springboot 自定义的全局捕获异常失效

背景&#xff1a;springbootspringcloud 分布式微服务。 问题&#xff1a;公共模块在使用RestControllerAdvice全局捕获异常时&#xff0c;捕获不到子服务抛出的相应异常 首先看一下全局异常组件有么有被扫描到 如何查看&#xff0c;很简单只需要写一段类加载打印代码&#x…

【hot100】跟着小王一起刷leetcode -- 739. 每日温度

【hot100】跟着小王一起刷leetcode -- 739. 每日温度 739. 每日温度题目解读思路 代码总结 739. 每日温度 题目解读 739. 每日温度 老规矩&#xff0c;咱先看下题目。总结下来就是&#xff0c;你要返回一个answer数组&#xff0c;answer[i]中存储的应该是temperatures数组中…

Android跨进程通信,binder传输数据过大导致客户端APP,Crash,异常捕获,监听异常的数值临界值,提前Hook拦截。

文章目录 Android跨进程通信&#xff0c;binder传输数据过大导致Crash&#xff0c;异常捕获&#xff0c;监听异常的数值临界值&#xff0c;提前Hook拦截。1.binder在做跨进程传输时&#xff0c;最大可以携带多少数据1.1有时候这个1m的崩溃系统捕获不到异常&#xff0c; 2.监测异…

深度学习与飞桨 PaddlePaddle Fluid

编辑推荐 飞桨PaddlePaddle是百度推出的深度学习框架&#xff0c;不仅支撑了百度公司的很多业务和应用&#xff0c;而且随着其开源过程的推进&#xff0c;在其他行业得到普及和应用。 本书基于2019年7月4日发布的飞桨PaddlePaddle Fluid 1.5版本&#xff08;后续版本会兼容旧版…

[工业网络] 模型建立

普渡大学ICS参考模型 普渡企业参考架构&#xff08;PERA&#xff09;是由西奥多J威廉姆斯&#xff08;Theodore J. Williams&#xff09;和普渡大学计算机集成制造工业大学联盟的成员在1990年代开发的企业架构参考模型。该模型被ISA-99&#xff08;现为ISA/IEC 62443&#xff…
最新文章