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

发布于:2025-09-10 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、数据库基础概念

1.1 数据库分类

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

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

1.2 常用核心名词

缩写 全称 核心作用
DB Database(数据库) 用于数据的存储、查询和更新,是数据的集合
DBMS Database Management System(数据库管理系统) 操作和管理数据库的软件,如 SQLite、MySQL
MIS Management Information System(管理信息系统) 基于数据库的企业管理系统,如 ERP、CRM
OA Office 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. 执行查询SQL
    char 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


网站公告

今日签到

点亮在社区的每一天
去签到