sqlite3编程接口非常多,对于初学者来说,我们暂时只需要掌握常用的几个函数,其他函数自然就知道如何使用了。

数据库

本篇假设数据库为my.db,有数据表student。

no name score
4 一口Linux 89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name text, score real);

常用函数

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);
功能:
打开sqlite数据库
参数:
path: 数据库文件路径
db: 指向sqlite句柄的指针,后面对数据库所有的操作都要依赖这个句柄
返回值:
成功返回0,失败返回错误码(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);
功能:
关闭sqlite数据库
返回值:
成功返回0,失败返回错误码
const  char  *sqlite3_errmsg(sqlite3 *db);
功能:
打印错误信息
返回值:
返回错误信息

不使用回调函数执行SQL语句

sqlite3_get_table


int sqlite3_get_table(sqlite3 *db, const char *sql, char ***resultp, int*nrow, int *ncolumn, char **errmsg);
功能:
执行SQL操作
参数:
db:数据库句柄
sql:SQL语句
resultp:用来指向sql执行结果的指针
nrow:满足条件的记录的数目
ncolumn:每条记录包含的字段数目
errmsg:错误信息指针的地址
返回值:
成功返回0,失败返回错误码

举例

下面比如我们要显示student表中所有的数据信息,我们就可以利用sqlite3_get_table()执行语句:

select * from student

实现代码如下:

void do_show_sample(sqlite3 *db)
{
char **result, *errmsg;
int nrow, ncolumn, i, j, index; if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
{
printf("error : %s\n", errmsg);
sqlite3_free(errmsg);
}
index = ncolumn;
for (i=0; i<nrow; i++)
{
for (j=0; j<ncolumn; j++)
{
printf("%-8s : %-8s\n", result[j], result[index]);
index++;
}
printf("************************\n");
}
sqlite3_free_table(result);
return;
}

假定当前的表格的数据信息如下:

no name score
4 一口Linux 77.0
5 一口peng 88.0
6 一口wang 99.0
7 一口网 66.0

关于这个函数中出现的这些参数的具体含义,我们可以见下图:

sqlite3编程接口非常多,对于初学者来说,我们暂时只需要掌握常用的几个函数,其他函数自然就知道如何使用了。

数据库

本篇假设数据库为my.db,有数据表student。

no name score
4 一口Linux 89.0

创建表格语句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name text, score real);

常用函数

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);
功能:
打开sqlite数据库
参数:
path: 数据库文件路径
db: 指向sqlite句柄的指针
返回值:
成功返回0,失败返回错误码(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);
功能:
关闭sqlite数据库
返回值:
成功返回0,失败返回错误码
const  char  *sqlite3_errmsg(sqlite3 *db);
功能:
打印错误信息
返回值:
返回错误信息

不使用回调函数执行SQL语句

sqlite3_get_table


int sqlite3_get_table(sqlite3 *db, const char *sql, char ***resultp, int*nrow, int *ncolumn, char **errmsg);
功能:
执行SQL操作
参数:
db:数据库句柄
sql:SQL语句
resultp:用来指向sql执行结果的指针
nrow:满足条件的记录的数目
ncolumn:每条记录包含的字段数目
errmsg:错误信息指针的地址
返回值:
成功返回0,失败返回错误码

举例

下面比如我们要显示student表中所有的数据信息,我们就可以利用sqlite3_get_table()执行语句:

select * from student

实现代码如下:

void do_show_sample(sqlite3 *db)
{
char **result, *errmsg;
int nrow, ncolumn, i, j, index; if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
{
printf("error : %s\n", errmsg);
sqlite3_free(errmsg);
}
index = ncolumn;
for (i=0; i<nrow; i++)
{
for (j=0; j<ncolumn; j++)
{
printf("%-8s : %-8s\n", result[j], result[index]);
index++;
}
printf("************************\n");
}
sqlite3_free_table(result);
return;
}

假定当前的表格的数据信息如下:

no name score
4 一口Linux 77.0
5 一口peng 88.0
6 一口wang 99.0
7 一口网 66.0

关于这个函数中出现的这些参数的具体含义,我们可以见下图:

由上图可知:

代码中:

ncolumn = 3
nrow = 5
result 指向所有的结果组成的字符串数组,
各个具体字符串的下标,图上已经标明。

结合此图再去理解代码,就很容易理解代码的实现原理。

使用回调函数执行SQL语句

sqlite3_exec

typedef  int (*sqlite3_callback)(void *, int, char **, char **);

int   sqlite3_exec(sqlite3 *db, const  char  *sql,  sqlite3_callback callback, void *,  char **errmsg);
功能:
执行SQL操作
参数:
db:数据库句柄
sql:SQL语句,就是我们前面两章用于操作表的增删改查语句
callback:回调函数
errmsg:错误信息指针的地址
返回值:
成功返回0,失败返回错误码

回调函数

typedef  int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);
功能:
每找到一条记录自动执行一次回调函数
参数:
para:传递给回调函数的参数
f_num:记录中包含的字段数目
f_value:包含每个字段值的指针数组
f_name:包含每个字段名称的指针数组
返回值:
成功返回0,失败返回-1

举例

sqlite3 *db;
char *errmsg,**resultp; int callback(void *para, int f_num, char **f_val, char **f_name)
{
int i; for (i=0; i<f_num; i++)
{
printf("%-8s", f_val[i]);
}
printf("\n"); return 0;
} void do_show(sqlite3 *db)
{
char *errmsg; printf("no name score\n"); if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0)
{
printf("error : %s\n", sqlite3_errmsg(db));
}
printf("\n"); return;
}

回调函数方法实现的代码,需要实现一个回调函数:callback。

函数sqlite3_exec()在解析命令"select * from student" ,没获取到一行数据就会调用一次回调函数,

参考上面的表格student,

callback()总共会被调用5次,
f_num 对应结果的列数,为3
f_value 则指向 每一列对应的值组成的字符串数组

假设现在callback是第四次被调用,如下图:

运行结果

编译需要使用第三方库lsqlite3。

gcc student.c -o run -lsqlite3

其他函数

sqlite3 *pdb, 数据库句柄,跟文件句柄FILE很类似
sqlite3_stmt *stmt, 这个相当于ODBC的Command对象,用于保存编译好的SQL语句 sqlite3_exec(), 执行非查询的sql语句
sqlite3_prepare(), 准备sql语句,执行select语句或者要使用parameter bind时,用这个函数(封装了sqlite3_exec)
Sqlite3_step(), 在调用sqlite3_prepare后,使用这个函数在记录集中移动

还有一系列的函数,用于从记录集字段中获取数据,如

sqlite3_column_text(), 取text类型的数据
sqlite3_column_blob(),取blob类型的数据
sqlite3_column_int(), 取int类型的数据

国际惯例,上完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sqlite3.h> void do_insert(sqlite3 *db)
{
int no;
char name[16];
float score;
char sqlstr[128], *errmsg; printf("input no : ");
scanf("%d", &no);
printf("input name : ");
scanf("%s", name);
printf("input score : ");
scanf("%f", &score);
sprintf(sqlstr, "insert into student values (%d, '%s', %.1f)",
no, name, score);
#if __DEBUG
printf("cmd:%s\n",sqlstr);
#endif
if (sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg) != 0)
{
printf("error : %s\n", sqlite3_errmsg(db));
}
else
{
printf("insert is done\n");
}
printf("\n"); return;
} void do_delete(sqlite3 *db)
{
char *errmsg;
char sqlstr[128], expression[64]; printf("input expression : ");
scanf("%s", expression);//name='ma'
sprintf(sqlstr, "delete from student where %s", expression);
#if __DEBUG
printf("cmd:%s\n",sqlstr);
#endif
if (sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg) != 0)
{
printf("error : %s\n", sqlite3_errmsg(db));
}
else
{
printf("deletet is done\n");
}
printf("\n"); return;
} int callback(void *para, int f_num, char **f_val, char **f_name)
{
int i; for (i=0; i<f_num; i++)
{
printf("%-8s", f_val[i]);
}
printf("\n"); return 0;
} void do_show(sqlite3 *db)
{
char *errmsg; printf("no name score\n"); if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0)
{
printf("error : %s\n", sqlite3_errmsg(db));
}
printf("\n"); return;
} void do_show_sample(sqlite3 *db)
{
char **result, *errmsg;
int nrow, ncolumn, i, j, index; if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
{
printf("error : %s\n", errmsg);
sqlite3_free(errmsg);
} index = ncolumn; for (i=0; i<nrow; i++)
{
for (j=0; j<ncolumn; j++)
{
printf("%-8s : %-8s\n", result[j], result[index]); index++;
}
printf("************************\n");
}
sqlite3_free_table(result); return;
} int main()
{
sqlite3 *db;
int n;
char clean[64]; if (sqlite3_open("my.db", &db) < 0)
{
printf("fail to sqlite3_open : %s\n", sqlite3_errmsg(db));
return -1;
} while ( 1 )
{
printf("*********************************************\n");
printf("1: insert record \n2: delete record \n3: show record \n4: quit\n");
printf("*********************************************\n");
printf("please select : "); if (scanf("%d", &n) != 1)
{
fgets(clean, 64, stdin);
printf("\n");
continue;
}
switch ( n )
{
case 1 :
do_insert(db);
break;
case 2 :
do_delete(db);
break;
case 3 :
do_show_sample(db);
break;
case 4 :
sqlite3_close(db);
exit(0);
}
}
return 0;
}

运行主页面:

插入记录:



显示记录:



删除记录:

完整代码,请关注公众号「一口Linux」

如何用C语言操作sqlite3,一文搞懂的更多相关文章

  1. Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!

    本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即时通讯网收录时有改动,感谢原作者的无私分享. 1.引言 典型的Web端即时通讯技术应用场景,主要有以下两种形式 ...

  2. 一文搞懂vim复制粘贴

    转载自本人独立博客https://liushiming.cn/2020/01/18/copy-and-paste-in-vim/ 概述 复制粘贴是文本编辑最常用的功能,但是在vim中复制粘贴还是有点麻 ...

  3. 三文搞懂学会Docker容器技术(中)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 6,Docker容器 6.1 创建并启动容器 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] --na ...

  4. 一文搞懂所有Java集合面试题

    Java集合 刚刚经历过秋招,看了大量的面经,顺便将常见的Java集合常考知识点总结了一下,并根据被问到的频率大致做了一个标注.一颗星表示知识点需要了解,被问到的频率不高,面试时起码能说个差不多.两颗 ...

  5. 一文搞懂Google Navigation Component

    一文搞懂Google Navigation Component 应用中的页面跳转是一个常规任务, Google官方提供的解决方案是Android Jetpack的Navigation componen ...

  6. 一文搞懂Flink Window机制

    Windows是处理无线数据流的核心,它将流分割成有限大小的桶(buckets),并在其上执行各种计算. 窗口化的Flink程序的结构通常如下,有分组流(keyed streams)和无分组流(non ...

  7. 一文搞懂RAM、ROM、SDRAM、DRAM、DDR、flash等存储介质

    一文搞懂RAM.ROM.SDRAM.DRAM.DDR.flash等存储介质 存储介质基本分类:ROM和RAM RAM:随机访问存储器(Random Access Memory),易失性.是与CPU直接 ...

  8. 基础篇|一文搞懂RNN(循环神经网络)

    基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...

  9. 一文搞懂 Prometheus 的直方图

    原文链接:一文搞懂 Prometheus 的直方图 Prometheus 中提供了四种指标类型(参考:Prometheus 的指标类型),其中直方图(Histogram)和摘要(Summary)是最复 ...

  10. 三文搞懂学会Docker容器技术(下)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 三文搞懂学会Docker容器技术(中) 7,Docker容器目录挂载 7.1 简介 容器目录挂载: 我们可以在创建容器的时候,将宿主机的目录与容器 ...

随机推荐

  1. 嵌入式编程的 4 种模型:轮询、中断、DMA、通道

    轮询方式 对I/O设备的程序轮询的方式,是早期的计算机系统对I/O设备的一种管理方式.它定时对各种设备轮流询问一遍有无处理要求.轮流询问之后,有要求的,则加以处理.在处理I/O设备的要求之后,处理机返 ...

  2. IPv6地址的文本表示规范

    背景 随着IPv6越来越普及,经常要跟IPv6地址打交道,迫切需要一个统一的IPv6地址文本表示规范. RFC4291简单的说明了如何将IPv6地址表示成文本形式,但有很多有歧义和不周全的地方. RF ...

  3. 使用kafka作为生产者生产数据到hdfs

    关键:查看kafka官网的userGuide 配置文件: agent.sources = r1agent.sinks = k1agent.channels = c1 ## sources config ...

  4. Python数据分析代码示例

    数据清洗 在进行数据分析之前,通常需要对原始数据进行清洗,即处理缺失值.异常值.重复值等问题. 下面是一个数据清洗的示例代码: import pandas as pd # 读取原始数据 data = ...

  5. 开发一个微信小程序流程及需要多少费用?

    流程如下: 小程序是一种新的开放能力,开发者可以快速地开发一个小程序.小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验. 开放注册范围:个人 企业 政府 媒体 其他组织 1.注册 在微信公 ...

  6. nuxt3正确使用keepalive页面缓存组件缓存

    最近使用nuxt@3.x版本做SEO优化项目比较多,之前也踩坑过,所以记录一下在 nuxt3 中路由缓存的正确使用方法,本人也之前在GitHub社区中提交过反馈问题,最后是在 3.8.2 版本解决了路 ...

  7. 零代码教你安装部署Stable Diffusion 3,一键生成高质量图像

    本文分享自华为云社区<重磅![支持中文]stable-diffusion-3安装部署教程-SD3 来了>,作者:码上开花_Lancer. 正如承诺的那样,Stability AI在6月12 ...

  8. 【原创软件】第2期:CAD文字快速批量替换工具CFR(CAD_FastReplace_V4)

    01 背景 由于工作需要,开发了一套CAD文字快速批量替换软件CFR.主要目的是:实现dwg文件一次性完成单对/多对词组快速批量替换. 02 主要功能特色 (1)无需打开CAD,快速实现文字批量替换. ...

  9. 解决方案 | 在 Tkinter 中导入 pywinauto/pyautogui 时窗口大小发生变化

    上面问题也可以换一个说法,pywinauto/pyautogui 时改变了tkinter的原有的窗口大小.这个问题困扰了我好几天而且网上有这样的问题但是并没有答案,今天摸索出答案给大家分享下.解决方法 ...

  10. Django配置为连接到Microsoft SQL Server

    可以将Django配置为连接到Microsoft SQL Server 2019.为此,你需要更改数据库设置中的一些配置选项.首先,确保你已经安装了 django 和 pyodbc 这两个库:   p ...