SQLite

关注公众号 jb51net

关闭
首页 > 数据库 > SQLite > Linux下SQLite实现

Linux环境下SQLite简单实现(附示例说明)

作者:!99%

SQLite是一个c语言库,它实现了一个小型、快速、自包含、高可靠性、全功能的SQL数据库引擎,也是世界上使用最多的数据库引擎,这篇文章主要介绍了Linux环境下SQLite简单实现的相关资料,需要的朋友可以参考下

SQLite 数据库常用操作指令总结

SQLite 是轻量级嵌入式数据库,无需服务端,操作指令简洁直观。以下按数据库管理、表操作、数据增删改查(CRUD)、进阶操作四大类,整理最常用的核心指令,并附示例说明。

一、数据库基础管理

SQLite 数据库以单个文件存储(如 test.db),以下指令用于数据库的创建、连接与状态查看。

操作目的

指令格式

示例与说明

连接/创建数据库

sqlite3 [数据库文件名]

sqlite3 test.db:若 test.db 存在则连接,不存在则在当前目录创建并连接。

查看当前连接的数据库

.database

执行后显示当前连接的数据库文件路径(如 main: test.dbmain 是默认数据库别名)。

退出 SQLite 命令行

.quit 或 .exit 或 Ctrl+D

输入 .quit 即可退出,所有操作自动持久化到数据库文件。

二、数据表核心操作

数据表是存储数据的载体,需先定义表结构(字段名、数据类型、约束),再进行后续操作。

1. 创建表(CREATE TABLE)

格式

CREATE TABLE [IF NOT EXISTS] 表名 (
    字段1 数据类型 [约束],
    字段2 数据类型 [约束],
    ...
    [主键约束/外键约束]
);

关键说明

示例:创建 user 表(存储用户信息)

CREATE TABLE IF NOT EXISTS user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,  -- 主键,自动递增(AUTOINCREMENT 仅 INTEGER 可用)
    name TEXT NOT NULL,                    -- 用户名,非空
    age INTEGER DEFAULT 18,                -- 年龄,默认18
    email TEXT UNIQUE,                     -- 邮箱,唯一(避免重复注册)
    create_time TEXT DEFAULT (datetime('now', 'localtime'))  -- 注册时间,默认当前本地时间
);

2. 查看表相关信息

操作目的

指令格式

示例与说明

查看所有表名

.tables

执行后显示当前数据库中所有表(如 user)。

查看表结构(字段详情)

.schema [表名] 或 PRAGMA table_info(表名);

.schema user:显示 user 表的创建语句;PRAGMA table_info(user);:以表格形式显示字段名、类型、约束。

3. 修改表结构(ALTER TABLE)

SQLite 对 ALTER TABLE 支持有限,仅支持重命名表添加字段,不支持删除/修改已有字段(需间接实现,如建新表迁移数据)。

操作目的

指令格式

示例与说明

重命名表

ALTER TABLE 旧表名 RENAME TO 新表名;

ALTER TABLE user RENAME TO users;:将 user 表改名为 users

给表添加新字段

ALTER TABLE 表名 ADD COLUMN 新字段 数据类型 [约束];

ALTER TABLE users ADD COLUMN phone TEXT;:给 users 表添加 phone 字段(字符串类型)。

4. 删除表(DROP TABLE)

格式

DROP TABLE [IF EXISTS] 表名;

示例

DROP TABLE IF EXISTS users;  -- 若 `users` 表存在则删除,避免报错

三、数据增删改查(CRUD)

数据表创建后,核心操作是对数据的新增、删除、修改和查询。

1. 新增数据(INSERT)

向表中插入一条或多条记录。

格式1:指定字段插入(推荐,字段顺序可自定义)

INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);

格式2:不指定字段(需按表结构字段顺序插入所有值)

INSERT INTO 表名 VALUES (值1, 值2, ...);  -- 主键若为 AUTOINCREMENT,可传 NULL 自动生成

格式3:批量插入

INSERT INTO 表名 (字段1, 字段2, ...) VALUES 
(值1-1, 值1-2, ...),
(值2-1, 值2-2, ...),
...;

示例:向 user 表插入数据

-- 1. 指定字段插入(忽略 id,自动递增;忽略 create_time,用默认时间)
INSERT INTO user (name, age, email) VALUES ('张三', 25, 'zhangsan@test.com');

-- 2. 批量插入
INSERT INTO user (name, age, email) VALUES 
('李四', 30, 'lisi@test.com'),
('王五', 22, 'wangwu@test.com');

注意:字符串值需用 '单引号' 包裹,数值类型直接写(如 25 无需引号)。

2. 查询数据(SELECT)

SQLite 最核心的操作,用于从表中筛选、排序、限制数据,语法灵活。

基础格式(查询所有字段/指定字段)

-- 查询指定字段
SELECT 字段1, 字段2, ... FROM 表名;

-- 查询所有字段(* 表示所有)
SELECT * FROM 表名;

带条件查询(WHERE)

筛选符合条件的记录,支持 =!=><>=<=LIKE(模糊匹配)、IN(范围匹配)等条件。

SELECT * FROM user WHERE age > 23;  -- 查询年龄大于23的用户
SELECT name, email FROM user WHERE email LIKE '%test.com';  -- 模糊匹配邮箱以 test.com 结尾的用户
SELECT * FROM user WHERE age IN (22, 25, 30);  -- 查询年龄为22、25、30的用户

排序(ORDER BY)

按指定字段升序(ASC,默认)或降序(DESC)排列结果。

SELECT * FROM user ORDER BY age DESC;  -- 按年龄降序排列(从大到小)
SELECT name, age FROM user ORDER BY age ASC, name DESC;  -- 先按年龄升序,再按姓名降序

限制结果数量(LIMIT)

只返回前 N 条记录,常用于分页(搭配 OFFSET 实现分页,OFFSET M 表示跳过前 M 条)。

SELECT * FROM user LIMIT 2;  -- 返回前2条记录
SELECT * FROM user ORDER BY age DESC LIMIT 2 OFFSET 1;  -- 跳过第1条,返回接下来的2条(即第2、3条)

去重(DISTINCT)

去除结果中重复的记录(基于指定字段)。

SELECT DISTINCT age FROM user;  -- 查询所有不重复的年龄

统计(COUNT/SUM/AVG 等聚合函数)

<code>SELECT COUNT(*) AS user_count FROM user;  -- 统计用户总数,结果列名用 AS 改为 user_count
SELECT AVG(age) AS avg_age FROM user;  -- 计算用户平均年龄
SELECT SUM(age) FROM user WHERE age > 25;  -- 计算年龄大于25的用户年龄总和</code>

3. 修改数据(UPDATE)

更新表中符合条件的记录,必须加 WHERE 条件,否则会修改所有记录

格式

UPDATE 表名 
SET 字段1=新值1, 字段2=新值2, ... 
[WHERE 条件];

示例

-- 将张三的年龄改为26(指定 WHERE 条件,仅修改张三)
UPDATE user SET age=26 WHERE name='张三';

-- 将所有年龄小于20的用户,默认年龄改为19(批量修改,需谨慎)
UPDATE user SET age=19 WHERE age < 20;

4. 删除数据(DELETE)

删除表中符合条件的记录,必须加 WHERE 条件,否则会删除所有记录

格式

DELETE FROM 表名 [WHERE 条件];

示例

-- 删除邮箱为 wangwu@test.com 的用户
DELETE FROM user WHERE email='wangwu@test.com';

-- 删除年龄大于35的用户
DELETE FROM user WHERE age > 35;

四、进阶操作

1. 事务管理(BEGIN/COMMIT/ROLLBACK)

SQLite 支持事务,确保一组操作要么全部成功,要么全部失败(避免数据不一致)。

示例:批量插入数据,出错则回滚

BEGIN;
INSERT INTO user (name, email) VALUES ('赵六', 'zhaoliu@test.com');
INSERT INTO user (name, email) VALUES ('孙七', 'sunqi@test.com');  -- 若此句报错(如邮箱重复)
COMMIT;  -- 报错则执行 ROLLBACK,两句插入都不生效

2. 索引(CREATE INDEX)

索引用于加速查询(尤其表数据量大时),但会增加插入/修改/删除的耗时(需维护索引)。

格式

CREATE [UNIQUE] INDEX [IF NOT EXISTS] 索引名 ON 表名 (字段1, 字段2, ...);

示例

-- 给 user 表的 email 字段创建唯一索引(避免重复,同时加速邮箱查询)
CREATE UNIQUE INDEX IF NOT EXISTS idx_user_email ON user (email);

-- 给 age 字段创建普通索引(加速年龄相关查询)
CREATE INDEX IF NOT EXISTS idx_user_age ON user (age);

删除索引

DROP INDEX IF EXISTS 索引名;  -- 如 DROP INDEX idx_user_age;

五、常用辅助指令(命令行特有)

SQLite 命令行中,以 . 开头的指令用于辅助操作,非 SQL 标准语法:

六、关键注意事项

SQLite3 C语言实现增删改查知识点小结

SQLite3 是轻量级嵌入式数据库,无需独立服务,通过 C 语言 API 可直接操作。以下总结核心知识点、常用 API 及简化版增删改查案例,避免复杂判断,聚焦基础功能实现。

一、核心知识点与常用 API

1. 编译与链接

2. 核心 API 说明

API 函数原型

功能说明

关键参数/返回值

sqlite3_open(const char *filename, sqlite3 **ppDb)

打开/创建数据库

filename:数据库文件路径(":memory:" 表示内存数据库)
ppDb:数据库句柄(操作数据库的核心标识)
- 返回值:SQLITE_OK 表示成功,非 0 为错误

sqlite3_exec(sqlite3 *db, const char *sql, sqlite3_callback callback, void *arg, char **errmsg)

执行 SQL 语句(增、删、改、查均可用,查需配合回调)

db:数据库句柄
sql:待执行的 SQL 字符串
callback:查询时的回调函数(增删改可设为 NULL
arg:传给回调函数的自定义参数(通常设为 NULL
errmsg:错误信息指针(需手动释放)
- 返回值:SQLITE_OK 表示成功

sqlite3_close(sqlite3 *db)

关闭数据库

- 需确保所有 SQL 操作完成后调用
- 若有未完成的事务,会自动回滚

sqlite3_free(char *errmsg)

释放错误信息内存

- 必须释放 sqlite3_exec 输出的 errmsg,避免内存泄漏

回调函数原型:
int callback(void *arg, int col_num, char **col_val, char **col_name)

查询时每行数据的处理函数(自动被 sqlite3_exec 调用)

col_num:当前行的列数
col_val:当前行各列的值(字符串形式,NULL 表示空值)
col_name:当前行各列的列名
- 返回值:0 表示继续遍历,非 0 表示终止查询

二、简化版增删改查案例

以下案例实现一个 student 表(包含 id 主键、name 姓名、age 年龄)的完整操作,代码无复杂判断,仅保留核心逻辑。

步骤 1:完整代码实现

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

// 1. 查询回调函数:打印每行查询结果
int query_callback(void *arg, int col_num, char **col_val, char **col_name) {
    // 打印列名(仅第一行数据时打印一次)
    static int is_first_row = 1;
    if (is_first_row) {
        for (int i = 0; i < col_num; i++) {
            printf("%-10s", col_name[i]); // 左对齐,占10字符
        }
        printf("\n");
        is_first_row = 0;
    }
    // 打印当前行数据
    for (int i = 0; i < col_num; i++) {
        // 若值为NULL,显示"NULL",否则显示值
        printf("%-10s", col_val[i] ? col_val[i] : "NULL");
    }
    printf("\n");
    return 0; // 继续遍历下一行
}

int main() {
    sqlite3 *db = NULL;    // 数据库句柄
    char *err_msg = NULL;  // 错误信息
    int ret;               // API返回值

    // 2. 打开/创建数据库(若不存在则自动创建)
    ret = sqlite3_open("student.db", &db);
    if (ret != SQLITE_OK) {
        printf("打开数据库失败:%s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 1;
    }
    printf("打开数据库成功!\n");

    // 3. 创建表(若表不存在则创建)
    const char *create_sql = "CREATE TABLE IF NOT EXISTS student ("
                             "id INT PRIMARY KEY,"  // 主键(唯一标识)
                             "name TEXT,"           // 姓名
                             "age INT);";           // 年龄
    ret = sqlite3_exec(db, create_sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK) {
        printf("创建表失败:%s\n", err_msg);
        sqlite3_free(err_msg); // 释放错误信息
        sqlite3_close(db);
        return 1;
    }
    printf("创建表成功(或表已存在)!\n");

    // 4. 插入数据(增)
    const char *insert_sql = "INSERT INTO student (id, name, age) "
                             "VALUES (1, 'Zhang San', 20), "  // 插入2条数据
                             "(2, 'Li Si', 21);";
    ret = sqlite3_exec(db, insert_sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK) {
        printf("插入数据失败(可能主键重复):%s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        printf("插入数据成功!\n");
    }

    // 5. 查询数据(查):调用回调函数处理结果
    printf("\n===== 查询所有学生数据 =====");
    const char *query_sql = "SELECT * FROM student;";
    ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
    if (ret != SQLITE_OK) {
        printf("查询数据失败:%s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);
        return 1;
    }

    // 6. 更新数据(改):修改Li Si的年龄为22
    const char *update_sql = "UPDATE student SET age = 22 WHERE name = 'Li Si';";
    ret = sqlite3_exec(db, update_sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK) {
        printf("\n更新数据失败:%s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        printf("\n更新数据成功(Li Si年龄改为22)!\n");
    }

    // 7. 再次查询,验证更新结果
    printf("\n===== 更新后的数据 =====");
    ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
    if (ret != SQLITE_OK) {
        printf("查询数据失败:%s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);
        return 1;
    }

    // 8. 删除数据(删):删除id=1的学生
    const char *delete_sql = "DELETE FROM student WHERE id = 1;";
    ret = sqlite3_exec(db, delete_sql, NULL, NULL, &err_msg);
    if (ret != SQLITE_OK) {
        printf("\n删除数据失败:%s\n", err_msg);
        sqlite3_free(err_msg);
    } else {
        printf("\n删除数据成功(删除id=1的学生)!\n");
    }

    // 9. 第三次查询,验证删除结果
    printf("\n===== 删除后的数据 =====");
    ret = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
    if (ret != SQLITE_OK) {
        printf("查询数据失败:%s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);
        return 1;
    }

    // 10. 关闭数据库
    sqlite3_close(db);
    printf("\n关闭数据库成功!\n");
    return 0;
}

步骤 2:代码说明与运行结果

关键逻辑解释

预期运行结果

打开数据库成功!
创建表成功(或表已存在)!
插入数据成功!

===== 查询所有学生数据 =====
id        name      age       
1         Zhang San 20       
2         Li Si     21       

更新数据成功(Li Si年龄改为22)!

===== 更新后的数据 =====
id        name      age       
1         Zhang San 20       
2         Li Si     22       

删除数据成功(删除id=1的学生)!

===== 删除后的数据 =====
id        name      age       
2         Li Si     22       

关闭数据库成功!

三、重点注意事项

总结 

到此这篇关于Linux环境下SQLite简单实现的文章就介绍到这了,更多相关Linux下SQLite实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文