SQLite数据库

SQLite3

SQLite 是一款轻量级、文件型、无服务端、零配置的关系型数据库

  • 没有独立服务器进程,数据库就是一个后缀 .db 的磁盘文件
  • 跨平台:Windows / Linux / Mac / 嵌入式 (STM32、树莓派、Android)
  • C 语言开发,体积很小,库文件几百 KB
  • 不需要账号密码,单文件数据库,适合本地、嵌入式、单机程序
  • 不支持高并发写操作;适合客户端、嵌入式、小型项目,不适合网站高并发后台

1. 打开 / 创建数据库

复制代码
sqlite3 test.db

如果 test.db 不存在,会新建文件;存在就打

开它

2.常用点命令以 . 开头,不是 SQL 语句

除了命令语句,所有的sql语句都要以分号结尾

复制代码
.help          -- 查看帮助
.tables        -- 列出所有表
.schema        -- 查看所有建表语句
.schema 表名    -- 查看某张表结构
.quit          -- 退出
.exit          -- 退出
.mode column   -- 列对齐显示结果
.headers on    -- 打开表头显示

3.创建一个表

复制代码
create table stu(sno int,name text,score float);

create table为命令格式。stu为表的名字,括号内,以逗号隔开每一个数据列,先写数据名,后写数据类型。数据类型具体如下

亲和类型 推荐写法 实际底层类型
TEXT 亲和 name TEXTname VARCHAR(32) TEXT
NUMERIC 亲和 age NUMERICbirthday DATE 优先存数字,也可存字符串
INTEGER 亲和 id INTEGERnum INT INTEGER
REAL 亲和 price REALweight FLOAT REAL
BLOB 亲和 data BLOB BLOB

4.插入一行数据

复制代码
insert into stu values(110,'tom',95.7);

insert into 为固定格式,stu为表的名字,valus也是固定格式,括号内数据要按照创建表的时候的格式写,因为这是插入一整行的数据,字符串可以用单引号也可以用双引号。

单独插入一行不全的数据

复制代码
insert into stu (sno,name) values(110,'tom');

5.查询表内的所有数据

复制代码
SELECT * FROM stu;

6.按条件查找某一行

复制代码
SELECT * FROM stu WHERE sno=110;

7.只查部分字段

复制代码
SELECT name,score FROM stu;

8.模糊查询

复制代码
SELECT * FROM stu WHERE name LIKE 'tom';

程序内通过函数操作sqlite数据库

打开与关闭数据库,操作与直接操作文件方法相同,直接对应文件名进行打开操作,但sqlite数据库需要定义为sqlite3 *类型的指针进行接收打开的文件描述符

复制代码
#include <stdio.h>
#include <sqlite3.h>

int main(void)
{
    sqlite3 *db;
    int ret;

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


    sqlite3_close(db);
    return 0;
}

执行无返回结果的建表、插入、更新、删除时,使用的函数

复制代码
int sqlite3_exec(
    sqlite3* db,                     // 数据库句柄
    const char *sql,                 // SQL字符串
    int (*callback)(void*,int,char**,char**), // 查询回调函数
    void *arg,                       // 传给回调的自定义参数
    char **errmsg                    // 错误信息输出
);

返回值
SQLITE_OK:成功
其他:失败

用函数操作,向表内插入数据

复制代码
char sql[][50] ={"insert into user values(110,'tom',123456);","insert into user values(111,'jack',666666);","insert into user values(112,'tom',888888);"};


for(int i = 0;i<3;i++)
{
	ret = sqlite3_exec(db,sql[i],NULL,NULL,&errmsg);

	if(ret != SQLITE_OK)
	{
		printf("sqlite3_exec fail:%s\n",errmsg);
		return -1;
	}
}

自定义callback回调函数,进行select查询操作

复制代码
/**
 * @brief     sqlite3_exec 查询结果回调函数
 * @param arg          自定义参数,此处传入表头打印标记变量的地址
 * @param columns_num  当前行的字段总数量
 * @param value        字符串数组,保存一行记录的数据内容
 * @param value_name   字符串数组,保存各个字段的名称(表头)
 * @return             返回0,表示回调处理正常结束
 */
int callback(void *arg,int columns_num,char **value,char **value_name)
{
	// 将void*通用指针转换为int指针,接收外部传入的表头标记
	int *first = (int *)arg;
	int i = 0;

	// 判断是否为第一次进入回调,只打印一次顶部分割线
	if(*first == 1)
	{
		printf("------------------------------\n");
		*first = 0;		// 修改标记,后续行不再打印顶部分隔线
	}

	// 循环打印表头(字段名)
	while(i<columns_num)
	{
		printf("%s\t",value_name[i]);
		i++;
	}
	putchar('\n');		// 表头打印完成后换行
	i = 0;				// 重置循环下标,准备打印本行数据

	// 循环打印当前一行每条字段的数据
	while(i<columns_num)
	{
		printf("%s\t",value[i]);
		i++;
	}
	putchar('\n');		// 当前一行数据打印完毕换行
	printf("------------------------------\n"); // 打印行底分隔线

	return 0;
}

    //调用执行select命令
	ret = sqlite3_exec(db,sql,callback,&head,&errmsg);

使用函数sqlite3_get_table直接查询表内容,无需定义callback

复制代码
// 定义sqlite3数据库句柄,初始化为空
sqlite3 *db = NULL;
// 打开(不存在则创建)test.db数据库,数据库句柄存入db
int ret = sqlite3_open("test.db",&db);

// 判断打开是否失败,SQLITE_OK代表成功
if(ret != SQLITE_OK)
{
	printf("sqlite3_open fail\n");
	return -1;
}

char *errmsg;       // 错误信息字符串指针
char **result;      // 存放查询结果的二维字符串数组

int row;            // 查询结果的数据行数(不包含表头字段名)
int col;            // 查询结果的列数(字段数量)

// sqlite3_get_table:执行SQL查询,结果存入result
// 参数依次:数据库句柄、sql语句、结果缓冲区、行数、列数、错误信息
ret = sqlite3_get_table(db,"select * from user;",&result,&row,&col,&errmsg);

// SQL执行失败判断
if(ret != SQLITE_OK)
{
	printf("sqlite3_exec fail:%s\n",errmsg);
	return -1;
}else 
{
	int i = 0;
	// 打印表头:result数组最前面存放的是每一列的字段名
	for(i=0;i<col;i++)
	{
		printf("%s\t",result[i]);
	}

	putchar('\n');  // 表头打印完成后换行

	// 循环遍历每一行数据
	for(int j = 0;j<row;j++)
	{
		// 打印一行里面的每一列单元格数据
		for(int n = 0;n<col;n++)
		{
			printf("%s\t",result[i]);
			i++;    // 数组下标向后偏移,取下一条数据
		}
		putchar('\n');  // 一行打印结束换行
	}
	// 释放sqlite3_get_table自动分配的结果内存,必须调用,否则内存泄漏
	sqlite3_free_table(result);
}

关闭已经打开的数据库文件
sqlite3_close(db);
相关推荐
云贝教育-郑老师30 分钟前
MySQL 的“黑匣子“:Performance Schema 把数据库内部变成一张可查的表
数据库·mysql
这个DBA有点耶2 小时前
同城双活落地的三座山:网络延迟、脑裂预防、反向同步
数据库·架构·dba
青春之我_XP2 小时前
MySQL 常用日期函数 实战指南
数据库·sql·mysql·数据分析·数据库开发·日期函数
Nturmoils2 小时前
sys_dump 备了库,角色和权限别漏在外面
数据库
接着奏乐接着舞。3 小时前
【2026】73道Redis 常见面试题与参考答案
数据库·redis·后端·缓存
其实防守也摸鱼4 小时前
权限提升与横向移动:从内网渗透到域控的完整技术图谱
运维·服务器·数据库·安全·github·copilot·渗透
人生百态,人生如梦4 小时前
每日论文解读(9.1)——ReToolSQL:面向鲁棒Text-to-SQL的Agentic强化学习与工具增强两阶段训练框架
数据库·sql
DevOpenClub4 小时前
网页采集如何稳定输出结构化数据:JSON、链接与快照三阶段流水线
数据库·json·api