当前位置: 首页 > news >正文

SQLite 数据库核心知识与 C 语言编程

一、数据库基础概念

1.1 数据库分类

根据规模和应用场景,数据库可分为以下几类:

  • 大型数据库:Oracle(适用于企业级高并发、大容量场景)
  • 中型数据库:MySQL、MSSQL(适用于中小型系统、Web 应用)
  • 小型数据库:SQLite、DB2(适用于嵌入式设备、轻量应用)

1.2 常用核心名词

缩写全称核心作用
DBDatabase(数据库)用于数据的存储、查询和更新,是数据的集合
DBMSDatabase Management System(数据库管理系统)操作和管理数据库的软件,如 SQLite、MySQL
MISManagement Information System(管理信息系统)基于数据库的企业管理系统,如 ERP、CRM
OAOffice Automation(办公自动化)基于数据库的协同办公系统,如考勤、审批

1.3 关系型数据库与 SQL 分类

关系型数据库基于表结构存储数据,通过SQL(Structured Query Language,结构化查询语言) 操作数据,SQL 按功能分为三类:

  • DDL(数据定义语言):用于定义数据库结构,如建表、删表
  • DML(数据操作语言):用于修改数据,如新增、更新、删除数据
  • DQL(数据查询语言):用于查询数据,如条件查询、排序查询

二、SQLite 核心特性

SQLite 是轻量级嵌入式数据库,无需独立服务器,核心特点如下:

  1. 开源免费:基于 C 语言开发,源代码完全开放
  2. 极致轻量:核心代码仅约 1 万行,编译后体积小于 10MB
  3. 无需安装:绿色软件,解压即可使用,无复杂配置
  4. 文件存储:整个数据库存储在单一文件中,便于移动和备份
  5. 容量充足:最大支持 2TB 数据存储,满足中小型应用需求
  6. 跨平台兼容:支持 Windows、Linux、macOS 等主流操作系统

三、SQLite 安装与基本使用

3.1 安装方法(Ubuntu/Debian 系统)

# 安装SQLite命令行工具
sudo apt-get install sqlite3
# 安装开发库(含头文件和静态库,用于C语言开发)
sudo apt-get install libsqlite3-dev
验证安装
# 查看SQLite版本
sqlite3 --version
# 查看帮助信息
sqlite3 --help
编译 C 程序
# 编译时需链接SQLite库和线程库
gcc test.c -lsqlite3 -lpthread -o test

3.2 基本使用(命令行)

1. 启动与退出
# 打开或创建名为test.db的数据库文件(不存在则自动创建)
sqlite3 test.db# 退出SQLite命令行(两种方式)
.q 或 .exit
  • 成功启动后显示 sqlite> 提示符
  • 若出现 ...> 提示符,说明命令未结束,需输入 ; 结束
2. 创建数据库
# 方法1:先创建空文件,再打开
touch test.db
sqlite3 test.db# 方法2:直接通过sqlite3命令创建并打开(推荐)
sqlite3 test.db

3.3 系统维护命令(以.开头)

命令功能描述
.database列出当前数据库及关联文件路径
.tables列出当前数据库中的所有表
.schema [表名]显示指定表的结构(CREATE 语句),无表名则显示所有表
.dump [表名]导出数据库或指定表的 SQL 脚本
.headers on/off开启 / 关闭查询结果的列标题显示
.exit退出 SQLite 程序

3.4 数据库导入与导出

导出数据库(备份)
# 将test.db数据库导出为SQL脚本backup.sql
sqlite3 test.db .dump > backup.sql
导入数据库(恢复)
# 将backup.sql脚本导入到new.db数据库(new.db不存在则创建)
sqlite3 new.db < backup.sql

四、SQL 基本语法

4.1 DDL(数据定义语言)

1. 创建表
-- 方式1:默认字段类型为TEXT
CREATE TABLE user(id, name, age);-- 方式2:指定字段类型(推荐)
CREATE TABLE user(id INT,        -- 整数类型name TEXT,     -- 文本类型age INT,       -- 整数类型dt DATETIME    -- 时间类型
);
  • SQLite 支持的数据类型:INT(整数)、TEXT(文本)、REAL(浮点数)、BLOB(二进制)
  • 若不指定类型,默认按TEXT处理
2. 删除表
-- 删除名为user的表(谨慎操作,数据不可恢复)
DROP TABLE user;

4.2 DML(数据操作语言)

1. 插入数据
-- 插入指定字段的数据(未指定字段值为NULL)
INSERT INTO user(id, age) VALUES(1, 10);-- 插入完整记录(需与表字段顺序一致)
INSERT INTO user VALUES(3, "wang", 11, datetime('now', '+8 hours'));-- 只插入部分字段(其余字段为NULL)
INSERT INTO user(age) VALUES(12);
  • datetime('now', '+8 hours'):获取当前东八区时间
2. 更新数据
-- 单条件更新:修改name为'li'的记录的id为1
UPDATE user SET id = 1 WHERE name = 'li';-- 多条件更新(AND):同时满足两个条件
UPDATE user SET id = 1 WHERE name = "li" AND passwd = "123";-- 多条件更新(OR):满足任一条件
UPDATE user SET id = 2 WHERE name = "li" OR name = "zhao";
3. 删除数据
-- 删除表中所有数据(谨慎操作,无条件删除)
DELETE FROM user;-- 单条件删除:删除id为1的记录
DELETE FROM user WHERE id = 1;-- 多条件删除(AND/OR)
DELETE FROM user WHERE id = 1 AND name = "zhang";
DELETE FROM user WHERE id = 1 OR id = 2;

4.3 DQL(数据查询语言)

1. 基本查询
-- 查询表中所有字段和数据
SELECT * FROM user;-- 查询指定字段
SELECT id FROM user;
SELECT id, name FROM user;
2. 条件查询
-- 逻辑条件查询(NOT):查询age不小于30的记录
SELECT * FROM user WHERE NOT age < 30;-- 模糊查询(LIKE):%匹配0-任意字符,_匹配1个字符
SELECT * FROM user WHERE name LIKE '张%';  -- 匹配姓张的所有记录
SELECT * FROM user WHERE name LIKE '张_';   -- 匹配姓张且名字为2个字的记录-- 排序查询(ORDER BY):ASC升序(默认),DESC降序
SELECT * FROM user ORDER BY id;          -- 按id升序
SELECT * FROM user ORDER BY id DESC;     -- 按id降序-- 限制结果数量(LIMIT):只返回前2条记录
SELECT * FROM user LIMIT 2;-- 组合查询:条件+排序+限制
SELECT * FROM user 
WHERE age > 20 OR age < 50 
ORDER BY age DESC 
LIMIT 2;

4.4 高级特性:自动增长列

SQLite 通过INTEGER PRIMARY KEY实现自动增长,无需AUTOINCREMENT

-- 创建含自动增长列的表
CREATE TABLE user3(id INTEGER PRIMARY KEY ASC,  -- ASC表示升序增长(默认)name TEXT,age INT,dt DATETIME
);-- 插入数据:id传入NULL触发自增(首条记录id=1,后续自动+1)
INSERT INTO user3 VALUES(NULL, '李四', 23, datetime('now'));

五、SQLite C 语言接口

5.1 开发环境准备

  • 头文件:#include <sqlite3.h>
  • 编译命令:gcc test.c -lsqlite3 -lpthread -o test

5.2 核心 API 函数

1. 打开数据库:sqlite3_open
int sqlite3_open(const char *path,  // 数据库文件路径(如"./test.db")sqlite3 **db       // 数据库连接句柄的指针(输出参数)
);
  • 功能:打开指定路径的数据库文件,不存在则创建
  • 返回值:成功返回SQLITE_OK(0),失败返回非 0 错误码
  • 错误处理:通过sqlite3_errmsg(db)获取错误信息
2. 关闭数据库:sqlite3_close
int sqlite3_close(sqlite3 *db);  // db:数据库连接句柄
  • 功能:关闭数据库连接
  • 返回值:成功返回SQLITE_OK,失败返回错误码
  • 注意:关闭前需确保所有 SQL 操作已完成
3. 执行 SQL 语句:sqlite3_exec
int sqlite3_exec(sqlite3 *db,                // 数据库连接句柄const char *sql,            // 要执行的SQL语句int (*callback)(void*,int,char**,char**),  // 回调函数(处理查询结果)void *arg,                  // 传递给回调函数的参数char **errmsg               // 错误信息指针(输出参数)
);
  • 功能:执行 SQL 语句(INSERT/UPDATE/DELETE/SELECT 等)
  • 回调函数:仅 SELECT 查询时需要,用于逐行处理结果;非查询语句可设为NULL
  • 错误处理:错误信息需通过sqlite3_free(errmsg)释放内存

5.3 回调函数定义

回调函数用于处理sqlite3_exec执行 SELECT 后的查询结果:

// 回调函数:逐行处理查询结果
static int callback(void *NotUsed,    // 用户自定义参数(由sqlite3_exec的arg传入)int argc,         // 结果列数char **argv,      // 结果数据数组(argv[i]为第i列的值,NULL表示空值)char **azColName  // 列名数组(azColName[i]为第i列的列名)
) {int i;// 遍历列数据,打印列名和对应值for (i = 0; i < argc; i++) {printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");}printf("\n");  // 每行数据后换行return 0;      // 返回0表示继续处理下一行,非0则中断
}

5.4 完整示例代码

示例 1:控制台输出查询结果
#include <stdio.h>
#include <sqlite3.h>// 回调函数:处理并打印查询结果
int show(void* arg, int col, char** result, char** title) {static int flag = 0;  // 标记是否首次调用(仅打印一次列名)int i = 0;// 首次调用:打印列名if (0 == flag) {flag = 1;for (i = 0; i < col; i++) {printf("%s\t", title[i]);}}// 打印当前行数据printf("\n");for (i = 0; i < col; i++) {printf("%s\t", result[i] ? result[i] : "NULL");}return 0;
}int main(int argc, char** argv) {sqlite3* db = NULL;       // 数据库连接句柄char* errmsg = NULL;      // 错误信息指针int ret;// 1. 打开数据库ret = sqlite3_open("./test.db", &db);if (SQLITE_OK != ret) {fprintf(stderr, "打开数据库失败:%s\n", sqlite3_errstr(ret));sqlite3_close(db);return 1;}// 2. 执行查询SQLchar sql_cmd[] = "SELECT * FROM user;";ret = sqlite3_exec(db, sql_cmd, show, NULL, &errmsg);if (SQLITE_OK != ret) {fprintf(stderr, "执行SQL失败:%s(SQL:%s)\n", errmsg, sql_cmd);sqlite3_free(errmsg);  // 释放错误信息内存sqlite3_close(db);return 1;}// 3. 关闭数据库sqlite3_close(db);return 0;
}
示例 2:查询结果写入文件
#include <stdio.h>
#include <sqlite3.h>// 回调函数:将查询结果写入文件
int show(void* arg, int col, char** result, char** title) {FILE* fp = (FILE*)arg;    // 传入的文件指针static int flag = 0;      // 标记是否首次调用int i = 0;// 首次调用:写入列名if (0 == flag) {flag = 1;for (i = 0; i < col; i++) {fprintf(fp, "%s\t", title[i]);}}// 写入当前行数据fprintf(fp, "\n");for (i = 0; i < col; i++) {fprintf(fp, "%s\t", result[i] ? result[i] : "NULL");}return 0;
}int main(int argc, char** argv) {sqlite3* db = NULL;char* errmsg = NULL;int ret;// 1. 打开数据库ret = sqlite3_open("./test.db", &db);if (SQLITE_OK != ret) {fprintf(stderr, "打开数据库失败:%s\n", sqlite3_errstr(ret));sqlite3_close(db);return 1;}// 2. 打开文件(用于写入结果)FILE* fp = fopen("result.txt", "w");if (NULL == fp) {perror("打开文件失败");sqlite3_close(db);return 1;}// 3. 执行查询SQL,将文件指针传入回调函数char sql_cmd[] = "SELECT * FROM user;";ret = sqlite3_exec(db, sql_cmd, show, fp, &errmsg);if (SQLITE_OK != ret) {fprintf(stderr, "执行SQL失败:%s(SQL:%s)\n", errmsg, sql_cmd);sqlite3_free(errmsg);sqlite3_close(db);fclose(fp);return 1;}// 4. 关闭资源fclose(fp);sqlite3_close(db);return 0;
}

5.5 运行示例

# 1. 编译代码
gcc query_to_file.c -lsqlite3 -lpthread -o query_to_file# 2. 执行程序(前提:test.db已存在且含user表)
./query_to_file# 3. 查看结果文件
cat result.txt

理想输出(result.txt)

id      name    age     dt
1       张三    23      2024-05-20 15:30:45
2       李四    25      2024-05-20 15:31:20


文章转载自:

http://45pUSMZl.kskpx.cn
http://bg9LhPGx.kskpx.cn
http://xHuba8OV.kskpx.cn
http://8G0nbq9p.kskpx.cn
http://C1eqOTXd.kskpx.cn
http://NmW6u8bG.kskpx.cn
http://btlJus7p.kskpx.cn
http://FHcvrmkD.kskpx.cn
http://qTFc1mOe.kskpx.cn
http://lQcuFLrz.kskpx.cn
http://wkHoXBec.kskpx.cn
http://P3hZX0oe.kskpx.cn
http://rTkDgeSj.kskpx.cn
http://H8HQQjg5.kskpx.cn
http://mQSEnWOu.kskpx.cn
http://zYN3vEkI.kskpx.cn
http://YzeyYVRu.kskpx.cn
http://NIRT6qPi.kskpx.cn
http://HA9JCkfd.kskpx.cn
http://suqS3hqs.kskpx.cn
http://CQK5JwVn.kskpx.cn
http://8lPdoAgj.kskpx.cn
http://5uWHHRf6.kskpx.cn
http://vvPcDDuC.kskpx.cn
http://ZZjxeCQr.kskpx.cn
http://FzUqB5u1.kskpx.cn
http://1Tp5mXQt.kskpx.cn
http://XcwX3eTd.kskpx.cn
http://j3tBwSfs.kskpx.cn
http://nDHN0WRW.kskpx.cn
http://www.dtcms.com/a/374361.html

相关文章:

  • unity中通过拖拽,自定义scroll view中子物体顺序
  • 最长上升子序列的长度最短连续字段和(动态规划)
  • 2025年最新AI大模型原理和应用面试题
  • Docker 轻量级管理Portainer
  • Aider AI Coding 智能上下文管理深度分析
  • 【Vue3】02-Vue3工程目录分析
  • JavaSE 集合从入门到面试:全面解析与实战指南
  • 《AI大模型应知应会100篇》第70篇:大模型驱动的自动化工具开发(国产化实战版)
  • 电机控制(四)-级联PID控制器与参数整定(MATLABSimulink)
  • mybatis-plus 的更新操作(个人资料更新) —— 前后端传参空值处理
  • 技术方案之数据迁移方案
  • LeetCode热题 15.三数之和(双指针)
  • 我对 OTA 的理解随记,附GD32/STM32例程
  • 快速构建数据集-假数据(生成划分)
  • c++ 杂记
  • Effective Modern C++ 条款26:避免在通用引用上重载
  • Android14 init.rc中on boot阶段操作4
  • PYQT5界面类继承以及软件功能开发小记
  • 【机器学习】吴恩达机器学习笔记
  • UE5 性能优化(1) 模型合并,材质合并
  • Selenium4+Pytest自动化测试框架实战
  • 基于RK3568多网多串(6网+6串+2光)1U/2U机架式服务器在储能与电力的应用
  • 【Python】运动路线记录GPX文件的操作API函数,以及相关GUI界面(支持复制、拼接、数据生成、修改,SRT字幕生成等功能)
  • 西嘎嘎学习 - C++vector容器 - Day 7
  • 第三章:Python基本语法规则详解(二)
  • Next系统总结学习(一)
  • 备考系统分析师-专栏介绍和目录
  • 【rk3229/rk3228a android7.1 LPDDR EMMC EMCP 批量sdk】
  • Kali 自带工具 dirb:Web 路径扫描与 edusrc 挖掘利器
  • 【系统分析师】第2章-基础知识:数学与工程基础(核心总结)