Linux应用 sqlite3编程

news2024/11/24 12:08:27

1、概念

SQLite3是一个轻量级的、自包含的、基于文件的数据库管理系统,常用于移动设备、嵌入式设备和小型应用程序中,应用场景如下:

  • 移动应用程序:由于SQLite3是零配置、无服务器的数据库引擎,非常适合用于移动应用程序中,如本地数据存储、离线访问等功能。

  • 嵌入式设备:SQLite3的小型性和零配置特性使得它成为许多嵌入式设备中的理想选择,包括智能家居设备、物联网设备等。

  • 小型应用程序:对于小型的桌面应用程序、小型网站等,SQLite3是一个不错的选择,因为它易于使用和部署。

2、常用命令

Ubuntu下使用apt-get install sqlite3安装。

2.1 创建数据库文件

直接使用sqlite3命令会将数据库创建在内存中,使用sqlite3 + 数据库名称可以将数据库文件创建到当前目录下,如果数据库文件已经存在则会打开:

2.2 创建表格

使用CREATE TABLE进行表格创建,对于以下示例:

CREATE TABLE users (id INTEGER PRIMARY KEY,name TEXT,age INTEGER);
  • CREATE TABLE users :这部分语句表示要创建一个名为users的表。
  • id INTEGER PRIMARY KEY,:这部分定义了第一个列(或字段)id,数据类型为INTEGER,并且将其定义为主键(PRIMARY KEY)。主键是用来唯一标识每一行记录的字段,可以保证表中每一行的唯一性。
  • name TEXT,:这部分定义了第二个列name,数据类型为TEXT,用来存储文本字符串类型的数据。 age INTEGER: 这部分定义了第三个列age,数据类型为INTEGER,用来存储整数类型的数据。

在此SQL语句中,id列被定义为主键,所以它的值必须是唯一的,并且不能为空。其他列name和age可以包含空值(NULL)。

2.3 查看表格

.tables命令可以查看表格,.schema可以查看表结构:

2.4 插入数据

使用INSERT INFO进行数据插入:

INSERT INTO users (name, age) VALUES ('张三', 25);
INSERT INTO users (name, age) VALUES ('李四', 30);

2.5 数据查询

使用SELECT 进行数据查询:

2.6 数据更新

使用UPDATE 进行数据更新:

2.7 数据删除

使用DELETE 进行数据删除:

2.8 退出

使用.exit命令退出。

3、C语言编程常用接口

执行apt-get install libsqlite3-dev安装开发文件,libsqlite3-dev是SQLite数据库的C语言接口的开发文件。它包含了用于在C/C++程序中访问SQLite数据库的头文件和静态库文件。

开发接口在官网中有介绍:An Introduction To The SQLite C/C++ Interface

3.1 sqlite3_open

打开一个SQLite数据库文件。

  • 原型:int sqlite3_open(const char *filename, sqlite3 **ppDb)
  • 入参:filename 为数据库文件名,ppDb 是指向 sqlite3* 结构体指针的指针
  • 返回值:返回 SQLITE_OK 表示成功,其它错误码表示失败
3.2 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 为回调函数接受的参数
  • 返回值:返回 SQLITE_OK 表示成功,其它错误码表示失败

回调函数的原型为 int (*callback)(void*, int, char**, char**)。具体来说:

  • void* 参数是通过 sqlite3_exec 的第四个参数传递给回调函数的自定义数据。
  • int 参数 argc 是结果集中返回的列数。
  • char** 参数 argv 是一个包含每一列的值的数组。
  • char** 参数 azColName 是一个包含每一列的列名的数组。
  • 回调函数应该返回一个整数值,非零值表示需要终止查询,0 表示继续执行。
3.3 sqlite3_prepare_v2

编译 SQL 语句并准备好一个语句对象,以便稍后执行和绑定参数。

  • 原型:int sqlite3_prepare_v2(sqlite3* db, const char* zSql, int nByte, sqlite3_stmt** ppStmt, const char** pzTail);

    • db:SQLite 数据库对象。
    • zSql:要编译的 SQL 语句。
    • nByte:SQL 语句的长度(-1 表示自动计算长度)。
    • ppStmt:返回的准备好的语句对象。
    • pzTail:指向剩余未使用的部分(可选)。
  • 返回值:如果 SQL 语句编译成功,则返回 SQLITE_OK,并将准备好的语句对象放入 ppStmt 中;如果出现错误,则返回对应的错误码。

3.4 sqlite3_step

用于执行准备好的语句对象,一次执行一步。

  • 原型:int sqlite3_step(sqlite3_stmt* pStmt);
  • 入参:准备好的语句对象。
  • 返回值:如果执行成功,返回 SQLITE_ROW 或 SQLITE_DONE;如果出现错误,返回其他错误码。
3.5 sqlite3_bind_int

将整数值绑定到 SQL 语句中的参数位置。

  • 原型:int sqlite3_bind_int(sqlite3_stmt* pStmt, int idx, int val);

    • pStmt:准备好的语句对象。
    • idx:参数的索引(1-based)。
    • val:要绑定的整数值。
  • 返回值:执行成功时返回 SQLITE_OK,否则返回对应的错误码。

3.6 sqlite3_finalize

用于释放准备好的语句对象。

  • 原型:int sqlite3_finalize(sqlite3_stmt* pStmt);
  • 入参:要释放的准备好的语句对象。
  • 返回值:成功时返回 SQLITE_OK,失败时返回其他错误码
3.7 sqlite3_close

关闭一个打开的SQLite数据库

  • 原型:int sqlite3_close(sqlite3*)
  • 入参:数据库指针
  • 返回值:返回 SQLITE_OK 表示成功,其它错误码表示失败
3.8 说明
  • sqlite3_finalize:释放由 sqlite3_prepare 或 sqlite3_prepare_v2 分配的准备语句对象。
  • sqlite3_free_table:释放通过 sqlite3_get_table 函数获得的结果表。
  • sqlite3_free_stmt:释放通过 sqlite3_prepare_v2 函数获得的语句对象。

理论上,可以说 sqlite3_exec 可以实现 sqlite3_prepare_v2 的功能,但是它们的设计和用途有所不同。

  • sqlite3_exec 主要用于执行一次性、不需要绑定参数的 SQL 语句操作,并且适合用于执行不返回结果集的 SQL 操作,比如创建表、插入数据、更新数据等。其优点在于简单直接,适用于简单的 SQL 操作。

  • sqlite3_prepare_v2 主要用于执行需要绑定参数、需要多次执行、或者需要获取结果集的 SQL 操作。通过预编译 SQL 语句,可以提高执行效率,并且可以使用参数绑定来防止 SQL 注入攻击。虽然在一些情况下可以通过拼接 SQL 语句并结合 sqlite3_exec 来模拟其功能,但不如 sqlite3_prepare_v2 灵活和安全。

4、编程示例

编写如下测试代码:

#include <sqlite3.h>
#include <stdio.h>

// 回调函数,用于在 sqlite3_exec 中处理查询结果
static int callback(void* NotUsed, int argc, char** argv, char** azColName) 
{
    for (int i = 0; i < argc; i++) 
    {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

int main() 
{
    sqlite3* db;
    char* errMsg = 0;

    // 打开数据库连接
    int rc = sqlite3_open("usr.db", &db);
    if (rc) 
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return rc;
    }

    // 创建表
    const char* createTableSQL = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);";
    rc = sqlite3_exec(db, createTableSQL, NULL, 0, &errMsg);
    if (rc != SQLITE_OK) 
    {
        fprintf(stderr, "SQL error: %s\n", errMsg);
        sqlite3_free(errMsg);
        sqlite3_close(db);
        return rc;
    }

    // 插入数据
    const char* insertDataSQL = "INSERT OR IGNORE INTO users (name, age) VALUES ('zhao', 30), ('qian', 25), ('sun', 35);";
    rc = sqlite3_exec(db, insertDataSQL, NULL, 0, &errMsg);
    if (rc != SQLITE_OK) 
    {
        fprintf(stderr, "SQL error: %s\n", errMsg);
        sqlite3_free(errMsg);
        sqlite3_close(db);
        return rc;
    }

    // 使用 sqlite3_exec 查询所有数据
    const char* selectDataSQL = "SELECT * FROM users;";
    rc = sqlite3_exec(db, selectDataSQL, callback, 0, &errMsg);
    if (rc != SQLITE_OK) 
    {
        fprintf(stderr, "SQL error: %s\n", errMsg);
        sqlite3_free(errMsg);
        sqlite3_close(db);
        return rc;
    }

    // 使用 sqlite3_prepare_v2 查询数据
    sqlite3_stmt* stmt;
    const char* selectDataSQL2 = "SELECT * FROM users WHERE age > ?;";
    rc = sqlite3_prepare_v2(db, selectDataSQL2, -1, &stmt, NULL);
    if (rc != SQLITE_OK) 
    {
        fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return rc;
    }

    // 检索年龄大于25的行
    int minAge = 25;
    sqlite3_bind_int(stmt, 1, minAge);

    while (sqlite3_step(stmt) == SQLITE_ROW)
    {
        printf("id = %d, name = %s, age = %d\n", sqlite3_column_int(stmt, 0), sqlite3_column_text(stmt, 1), sqlite3_column_int(stmt, 2));
    }

    sqlite3_finalize(stmt);

    // 关闭数据库连接
    sqlite3_close(db);

    return 0;
}

测试结果如下:

5、总结

本文讲解了sqlite3的常用命令和c语言编程的常用接口,并编写测试用例进行测试。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)

导航&#xff1a; 本文一些内容需要聚簇索引、非聚簇索引、B树、覆盖索引、索引下推等前置概念&#xff0c;虽然本文有简单回顾&#xff0c;但详细可以参考下文的【MySQL高级篇】 【Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成…

[Cesium]加载GeoJSON并自定义设置符号(以点要素为例)

数据准备&#xff1a; Geoserver发布WFS&#xff08;Web Feature Service&#xff09;服务 [GeoServer系列]Shapefile数据发布-CSDN博客 数据加载&#xff1a; 数据准备第二种方式加载数据&#xff0c;利用for循环加载多个图层。首先将获取数据(每获取一次获得pomise,将其加入…

SQL优化系列-快速学会分析SQL执行效率(下)

1 show profile 分析慢查询 有时需要确定 SQL 到底慢在哪个环节&#xff0c;此时 explain 可能不好确定。在 MySQL 数据库中&#xff0c;通过 profile&#xff0c;能够更清楚地了解 SQL 执行过程的资源使用情况&#xff0c;能让我们知道到底慢在哪个环节。 知识扩展&#xff1…

Wireshark 如何查找包含特定数据的数据帧

1、查找包含特定 string 的数据帧 使用如下指令&#xff1a; 双引号中所要查找的字符串 frame contains "xxx" 查找字符串 “heartbeat” 示例&#xff1a; 2、查找包含特定16进制的数据帧 使用如下指令&#xff1a; TCP&#xff1a;在TCP流中查找 tcp contai…

汽车分销商文件流转优化:实现稳定高效的文件分发处理

在汽车圈里&#xff0c;分销商可是个不可或缺的角色。他们既要跟汽车厂家紧紧绑在一起&#xff0c;还得跟下游的销售渠道或者直接跟消费者打成一片&#xff0c;文件来回传递那是家常便饭。 这文件发放的速度快不快&#xff0c;安不安全&#xff0c;直接影响到分销商做事的效率…

容器(Docker)安装

centos安装Docker sudo yum remove docker* sudo yum install -y yum-utils#配置docker的yum地址 sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo#安装指定版本 - 可以根据实际安装版本 sudo yum install -y docke…

Centos 报错 One of the configured repositories failed

目录预览 一、问题描述二、原因分析三、解决方案四、参考链接 一、问题描述 使用yum update更新命令就出现下面问题&#xff0c;系统是刚安装的&#xff0c;然后修改了一下IP变成手动。&#xff08;排查问题前&#xff0c;先回顾自己做了哪些操作&#xff0c;方便进一步排错&a…

策略模式的理解和运用

在之前的小游戏项目中&#xff0c;处理websocket长连接请求的时候&#xff0c;需要根据传递数据包的不同类型&#xff0c;进行不同的处理。为了实现这个场景&#xff0c;比较简单的方法就是使用if-else或者switch-case语句&#xff0c;根据条件进行判断。但是这导致了项目代码复…

梦幻西游外网架设教程-端游篇

《梦幻西游》是一款由中国网易公司自行开发并营运的网络国产游戏。游戏以著名的章回小说《西游记》故事为背景&#xff0c;透过Q版的人物&#xff0c;试图营造出浪漫的网络游戏风格。 《梦幻西游》拥有注册用户超过3.1亿&#xff0c;一共开设收费服务器达472组&#xff0c;最高…

Sigmoid图像

import matplotlib.pyplot as plt import numpy as npdef sigmoid(x):# 直接返回sigmoid函数return 1. / (1. np.exp((0.7 -(x))/0.075))def plot_sigmoid():# param:起点&#xff0c;终点&#xff0c;间距x np.arange(0, 1, 1 / 16000)y sigmoid(x)plt.plot(x, y)plt.show…

【WP】猿人学_19_乌拉乌拉乌拉

https://match.yuanrenxue.cn/match/19 发包测试 经过发包测试&#xff0c;并没有携带加密参数&#xff0c;但是使用python无法复现&#xff0c;requests&#xff0c;httpx以及异步都不行&#xff0c;网上搜索了一下&#xff0c;这是使用了JA3指纹。可能是我做的时间比较晚&…

【iOS】UI学习——导航控制器、分栏控制器

UI学习&#xff08;三&#xff09; 导航控制器导航控制器基础导航控制器切换导航栏和工具栏 分栏控制器分栏控制器基础分栏控制器高级 导航控制器 导航控制器负责控制导航栏&#xff08;navigationBar&#xff09;&#xff0c;导航栏上的按钮叫UINavigationItem&#xff08;导航…

【论文阅读】SELF-RAG,让模型决策和反思检索

关于LLM何时使用RAG的问题&#xff0c;原本是阅读了关于ADAPT-LLM模型的那篇论文&#xff0c;被问到与SELF-RAG有何区别。所以&#xff0c;大概看了一下SELF-RAG这篇论文&#xff0c;确实很像&#xff0c;这些基于LLM针对下游任务的模型架构和方法&#xff0c;本来就很像。不过…

accelerate笔记:实验跟踪

Accelerate支持七种集成的跟踪器&#xff1a; TensorBoardWandBCometMLAimMLFlowClearMLDVCLive要使用这些跟踪器&#xff0c;可以通过在 Accelerator 类的 log_with 参数中传入所选类型来实现 from accelerate import Accelerator from accelerate.utils import LoggerTypeac…

Yolo-v5模型训练速度,与GeForce的AI算力描述

1.GeForce RTX3070 Ti官网参数&#xff1a; GeForce RTXTM 3070 Ti 和 RTX 3070 显卡采用第 2 代 NVIDIA RTX 架构 - NVIDIA Ampere 架构。该系列产品搭载专用的第 2 代 RT Core &#xff0c;第 3 代 Tensor Core、全新的 SM 多单元流处理器以及高速显存&#xff0c;助您在高性…

北斗RTK+UWB定位的优势

在当今科技飞速发展的时代&#xff0c;定位技术的应用已渗透到我们生活的方方面面。从导航、物流到无人驾驶、智能制造&#xff0c;精准定位技术无处不在。而北斗RTK&#xff08;Real-Time Kinematic&#xff0c;实时动态&#xff09;和UWB&#xff08;Ultra-Wideband&#xff…

闭眼推荐的,新手教师工具

亲爱的老师们&#xff0c;尤其是那些刚踏入教育界的新手教师们&#xff0c;还在为如何高效管理课堂、如何制作精美的教学材料而头疼吗&#xff1f;让我来分享几款教育界口碑爆棚的工具。 易查分小程序 易查分是一款超级方便的成绩查询工具&#xff0c;一分钟就能上传成绩并生成…

[经验] 腰果树的外观特征和特点是什么 #媒体#微信

腰果树的外观特征和特点是什么 腰果树是一种生长在热带和亚热带地区的落叶乔木&#xff0c;其叶子为互生&#xff0c;倒披针形或披针形&#xff0c;整个树枝条生长勃勃&#xff0c;长势喜人。 腰果树的树皮是灰色或深褐色的&#xff0c;有着纵向裂缝&#xff0c;树皮粗糙而有光…

【Mybatis】源码分析-高级应用

1、Mybatis配置文件深入理解 1.2、动态SQL语句 Mybatis 的映射⽂件中&#xff0c;前⾯我们的 SQL 都是⽐较简单的&#xff0c;有些时候业务逻辑复杂时&#xff0c;我们的 SQL是动态变化的&#xff0c;此时在前⾯的学习中我们的 SQL 就不能满⾜要求了。 1.2.1、条件判断 我们根…

OrangePi KunPengPro | linux系统下挂载U盘

OrangePi KunPengPro | linux系统下挂载U盘 时间&#xff1a;2024年6月6日21:32:53 文章目录 OrangePi KunPengPro | linux系统下挂载U盘1.参考2.操作fdisk -l 列出系统上所有磁盘的分区表信息将 /dev/sda1 分区挂载到 /mnt/udisk/ 目录显示文件系统的磁盘空间使用情况卸载文件…