SQLite库笔记:API函数编程

news2024/11/13 15:19:26

本文主要介绍SQLite库的一些核心API函数,和实现数据库增删查改功能的C语言示例程序代码。

目录

1. API函数原型

1.1 sqlite3_open

1.2 sqlite3_close

1.3 sqlite3_free

1.4 sqlite3_errmsg

1.5 sqlite3_exec

1.6 sqlite3_get_table

1.7 sqlite3_free_table

2. 返回码定义

3. 示例程序

3.1 数据库表设计

3.2 代码

3.3 编译运行


1. API函数原型

SQLite库有两百多个API,下面列出几个核心的API。

1.1 sqlite3_open

函数声明    

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

描述  

打开数据库文件

参数

filename[输入]  

数据库文件名 (UTF-8)

ppDb[输出]  

 SQLite db句柄

返回值

0-成功,其它-失败

1.2 sqlite3_close

函数声明    

int sqlite3_close(sqlite3* pDb);

描述  

关闭数据库db句柄

参数

pDb[输入]

数据库db句柄

返回值

0-成功,其它-失败

1.3 sqlite3_free

函数声明    

void sqlite3_free(void* ptr);

描述  

释放指针数据

参数

Ptr[输入]

指针数据

返回值

1.4 sqlite3_errmsg

函数声明    

const char *sqlite3_errmsg(sqlite3* pDb);

描述  

获取具体的错误信息

参数

pDb[输入]

数据库db句柄

返回值

错误信息字符串

1.5 sqlite3_exec

函数声明    

int sqlite3_exec(sqlite3*db, const char *sql,

                        int (*callback)(void*,int,char**,char**), void *arg, char **errmsg);

描述  

运行SQL语句

参数

db[输入]

一个打开的数据库db句柄

Sql[输入]

要执行的SQL语句

callback [输入]

回调函数

arg[输入]

回调函数的第一个参数

errmsg[输出]

错误信息

返回值

0-成功,其它-失败

1.6 sqlite3_get_table

函数声明    

int sqlite3_get_table(sqlite3 *db, const char *zSql, char ***pazResult,

                                int *pnRow, int *pnColumn, char **pzErrmsg);

描述  

运行SQL查询语句

参数

db[输入]

一个打开的数据库db句柄

zSql[输入]

要执行的SQL语句

pazResult[输出]

查询的结果

pnRow[输出]

查询结果的行数

pnColumn[输出]

查询结果的列数

pzErrmsg[输出]

错误信息

返回值

0-成功,其它-失败

1.7 sqlite3_free_table

函数声明    

void sqlite3_free_table(char **result);

描述  

释放SQL查询结果指针

参数

result [输入]

查询的结果

返回值

2. 返回码定义

sqlite3.h中常遇到的返回码

含义

SQLITE_OK (0)

成功

SQLITE_ERROR (1)

通用返回码

SQLITE_INTERNAL (2)

内部故障

SQLITE_PERM (3)

无法提供新创建的数据库的请求访问模式

SQLITE_ABORT (4)

操作中断

SQLITE_BUSY (5)

由于其它数据库连接的并发活动,无法读写

SQLITE_LOCKED (6)

连接冲突,写操作失败

3. 示例程序

3.1 数据库表设计

元素

类型

说明

id

int

货物ID

name

char(16)

货物名称

supplier

char(16)

供应商

ymdhms

datetime

年-月-日 时:分:秒

unit

int

单价

num

int

数量

sum

int

总价

3.2 代码

下面的代码实现了数据库的基本功能操作,包括:

  • 创建数据库文件test.db
  • 创建数据库表purchase
  • 向数据库表中插入数据
  • 修改数据库表的数据
  • 删除数据库表中特定ID的数据
  • 查询数据库表中数据条目数量
  • 查询数据库表中所有数据
/*  This is a demo using the SQLite library API functions.
 *  More details about SQLite: https://www.sqlite.org/
 */

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

#define DEBUG_PRINTF(format, ...)   printf("<%s, %d> "format" ", __func__, __LINE__, ## __VA_ARGS__)
#define ARRAY_SIZE(_arr)		    (sizeof((_arr)) / sizeof((_arr)[0]))
#define PURCHASE_DB_FILE			"test.db"

typedef struct _purchase_para{
	int id;
	char name[16];
	char supplier[16];
	char ymdhms[24];
	int unit;
	int num;
	int sum;
}purchase_para;

int iDBInit(sqlite3 **ppDb)
{
	char *err = NULL;
	char sql[256] = {0};
	int ret;

	/* database init */
	ret = sqlite3_open(PURCHASE_DB_FILE, ppDb);
	if (ret != SQLITE_OK) {
		DEBUG_PRINTF("sqlite3_open ret:%d, msg:%s\n", ret, sqlite3_errmsg(*ppDb));
		sqlite3_close(*ppDb);
		return -1;
	}

	snprintf(sql, sizeof(sql), 
		"create table if not exists purchase \
			(id int, \
			name char(16), \
			supplier char(16), \
   			ymdhms datetime,\
			unit int, \
			num int, \
			sum int, \
   			primary key(id, ymdhms));"
		);
	ret = sqlite3_exec(*ppDb , sql , NULL , NULL , &err);
	if (ret != SQLITE_OK) {
		DEBUG_PRINTF("sqlite3_exec ret:%d, %s\n", ret, err);
		sqlite3_free(err);
	}

	return 0;
}

void vDBFree(sqlite3 *pDb)
{
	if (pDb != NULL) {
		sqlite3_close(pDb);
		pDb = NULL;
	}
}

/* insert data */
int iDBInsert(sqlite3 *pDb, purchase_para *pdata)
{
	char sql[256] = {0};
	char *errmsg = NULL;
	int ret;

	if (pDb == NULL || pdata == NULL) {
		return -1;
	}

	snprintf(sql, sizeof(sql), 
			"insert into purchase(id, name, supplier, ymdhms, unit, num, sum) \
			values(%d, '%s', '%s', '%s', %d, %d, %d);", 
			pdata->id, pdata->name, pdata->supplier, pdata->ymdhms, 
			pdata->unit, pdata->num, pdata->sum);

	ret = sqlite3_exec(pDb , sql , NULL , NULL , &errmsg);
	if (ret != SQLITE_OK) {
		DEBUG_PRINTF("sqlite3_exec ret:%d, %s\n", ret, errmsg);
		sqlite3_free(errmsg);
	}
	return ret;
}

/* modify data if id matches */
int iDBUpdateByID(sqlite3 *pDb, purchase_para *pdata)
{
	char sql[256] = {0};
	char *errmsg = NULL;
	int ret;

	if (pDb == NULL || pdata == NULL) {
		return -1;
	}

	snprintf(sql, sizeof(sql), 
		"update purchase set name = '%s', supplier = '%s', ymdhms = '%s', \
        unit = %d, num = %d, sum = %d where id == %d;",
		pdata->name, pdata->supplier, pdata->ymdhms, 
		pdata->unit, pdata->num, pdata->sum, pdata->id);

	ret = sqlite3_exec(pDb , sql , NULL , NULL , &errmsg);
	if (ret != SQLITE_OK) {
		DEBUG_PRINTF("sqlite3_exec ret:%d, %s\n", ret, errmsg);
		sqlite3_free(errmsg);
	}
	return ret;
}

/* delete data if id matches */
int iDBDelByID(sqlite3 *pDb, int id)
{
	int ret = 0;
	char sql[64] = {0};
	char *errmsg = NULL;
	
	if (pDb == NULL) {
		return -1;
	}

	snprintf(sql, sizeof(sql), 
		"delete from purchase where id == %d;vacuum;", id);
	
	ret = sqlite3_exec(pDb , sql , NULL , NULL , &errmsg);
	if (ret != SQLITE_OK) {
		DEBUG_PRINTF("<%s> sqlite3_exec ret:%d, %s\n", __func__, ret, errmsg);
		sqlite3_free(errmsg);
	}
	return ret;
}

/* query the number of database data items */
int iDBQueryCnt(sqlite3 *pDb, int *cnt)
{
	int ret = 0;
	int row = 0;
	int column = 0;
	char **result;
	char sql[64] = {0};
	char *errmsg = NULL;
	
	snprintf(sql, sizeof(sql), "select count(*) from purchase;");

	ret = sqlite3_get_table(pDb , sql , &result , &row , &column , &errmsg);
	if (ret != SQLITE_OK) {
		DEBUG_PRINTF("<%s> sqlite3_exec ret:%d, %s\n", __func__, ret, errmsg);
		sqlite3_free(errmsg);
	}
	else {
		*cnt = atoi(result[1]);
		DEBUG_PRINTF("select successfully, row:%d, col:%d, cnt:%d\n", row, column, *cnt);		
	}
	sqlite3_free_table(result);
	return ret;
}

/* query all data in the database */
int iDBQueryAll(sqlite3 *pDb)
{
	int ret = 0;
	int row = 0;
	int column = 0;
	int i, j;
	char **result;
	char sql[64] = {0};
	char *errmsg = NULL;
	
	snprintf(sql, sizeof(sql), "select * from purchase;");

	ret = sqlite3_get_table(pDb , sql , &result , &row , &column , &errmsg);
	if (ret != SQLITE_OK) {
		DEBUG_PRINTF("<%s> sqlite3_exec ret:%d, %s\n", __func__, ret, errmsg);
		sqlite3_free(errmsg);
	}
	else {
		DEBUG_PRINTF("select successfully, row:%d, col:%d, data:\n", row, column);
		for(i = 0; i <= row; i++)
		{
			for(j = 0; j < column; j++)
			{
				printf("%s, ", result[i * column + j]);
			}
			printf("\n");
		}	
	}
	sqlite3_free_table(result);
	return ret;
}

测试示例

static void vTestInsert(sqlite3 *pDb)
{
	int i;
	int errcnt = 0;
	struct tm *timeinfo = NULL;
	time_t time_now;
	purchase_para data[] = {
		/*{1, "pencil", "sunny", "2024-07-10 12:06:35", 2, 100, 200},*/
		{1, "pencil", "sunny",  "", 2,  100, 200},
		{2, "pen",    "sky",    "", 10, 100, 1000},
		{3, "eraser", "lily",   "", 1,  80,  80},
		{4, "ruler",   "sunny", "", 2,  200, 400},
	};

	time(&time_now);
	timeinfo = localtime(&time_now);

	for(i = 0; i < ARRAY_SIZE(data); i++)
	{
		timeinfo->tm_mon = (timeinfo->tm_mon - i) % 12;
		strftime(data[i].ymdhms, ARRAY_SIZE(data[i].ymdhms), "%Y-%m-%d %H:%M:%S", timeinfo);
		if (iDBInsert(pDb, &data[i]) != 0) {
			errcnt++;
		}
	}
	DEBUG_PRINTF("insert %s\n", (errcnt == 0) ? "succ" : "fail");
}

static void vTestModify(sqlite3 *pDb)
{
	int ret;
	struct tm *timeinfo = NULL;
	time_t time_now;
	purchase_para data = {3, "eraser", "lily", "", 2, 80, 160};

	/* change the ymdhms to the current date and time */
	time(&time_now);
	timeinfo = localtime(&time_now);
	strftime(data.ymdhms, ARRAY_SIZE(data.ymdhms), "%Y-%m-%d %H:%M:%S", timeinfo);

	/* update data */
	ret = iDBUpdateByID(pDb, &data);
	DEBUG_PRINTF("modify %s\n", (ret == 0) ? "succ" : "fail");
}

int main(int argc, char* argv[])
{
	sqlite3 *ptrDb = NULL;
	int cnt = 0;
	int ret;

	if (iDBInit(&ptrDb) != 0) {
		return -1;
	}

	/* Query the number of database data items  */
	iDBQueryCnt(ptrDb, &cnt);
	/* Query all data in the database */
	iDBQueryAll(ptrDb);

	/* Insert some data */
	vTestInsert(ptrDb);
	/* modify data if id=3 */
	vTestModify(ptrDb);
	iDBQueryAll(ptrDb);

	/* delete data if id=4 */
	ret = iDBDelByID(ptrDb, 4);
	DEBUG_PRINTF("delete data %s\n", (ret == 0) ? "succ" : "fail");

	iDBQueryAll(ptrDb);

	vDBFree(ptrDb);
    return 0;
}

3.3 编译运行

将SQLite库编译生成的include和lib文件夹拷贝到工程目录下,编译加上-lsqlite3链接参数。编译示例如下:

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1974397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot废物回收管理商城-计算机毕业设计源码18221

基于Spring boot的废物回收管理商城 摘要 本研究基于Spring Boot框架设计并开发了一款废物回收管理商城系统&#xff0c;旨在有效整合废物回收资源&#xff0c;提高废物回收的效率和便捷性。通过对废物回收市场的调研与分析&#xff0c;结合现代互联网技术和物联网技术&#…

Docker Buildx 简介与安装指南

目录 1.Docker Buildx 简介 1. 引言 2. Docker Buildx 的背景和意义 3. Docker Buildx 的主要特性 4. 为什么选择 Docker Buildx 2.激活 Docker 实验性特性&#xff1a;一步设置 3.比如ARM架构下的Docker Buildx未自带 4.重启docker &#x1f310; 无论你是初学者还是经…

非递归的归并排序

我们之前讲的快速排序有非递归的写法&#xff0c;那么归并排序也有非递归写法&#xff0c;我们一起来研究一下吧。 快速排序的非递归算法是使用的手动搭栈的方法&#xff0c;将区间存入栈里面&#xff0c;然后再排序&#xff0c;但是这次的归并排序可以吗&#xff1f;大家都知…

WebLogic 8.x中间件监控指标解读

监控易是一款功能强大的IT监控系统&#xff0c;能够全面监控各类IT设施的运行状态&#xff0c;及时发现并解决潜在问题。针对WebLogic 8.x中间件的监控&#xff0c;监控易提供了一系列详尽的指标&#xff0c;确保WebLogic集群和应用的稳定运行。 在WebLogic集群监控方面&#x…

OSPF路由协议----开放式最短路径优先

一、为什么需要OSPF? 1、RIP以跳数评估的路由并非最优路径 传输时间T=2Mps/64Kbps=32s 如果选择S0/0传输,传输时间T=2Mps/2Mps+2Mps/2Mps+2Mps/2Mps=3s 时长大大缩短。 2、RIP的最大跳数为16,网络尺度小 RIP协议限制网络直径不能朝超过16跳,只适用于小型网。 3、RIP收…

登录谷歌账号时无法登录,提示“您正常是在一部Google无法识别的设备上登录”,原因和如何解决?

这段时间&#xff0c;有几个朋友联系GG账号服务&#xff0c;说她们在登录谷歌账号的时候&#xff0c;提示Google账号无法登录&#xff0c;提示&#xff1a;您正尝试在一部Google无法识别的设备上登录&#xff0c;我们没有足够的信息来验证您的身份。为了安全起见&#xff0c;您…

浦语提示词工程实践

第一次 -失败 修改后&#xff1a;

中缀与前缀表达式之间的转换

文章目录 中缀表达式转前缀表达式总结参考链接 中缀表达式转前缀表达式 前缀表达式&#xff0c;又称波兰表达式&#xff0c;是一种编写算术表达式的方法&#xff0c;其中运算符位于操作数之前。 下面给出一种中缀表达式转前缀表达式的方法&#xff0c;利用辅助栈。 其规责如下…

朱锐 | 生命图像中的时间和意识

本文载于《科学・经济・社会》2023 年第 41 卷第 2 期第 37~61 页 作者简介&#xff1a; 朱锐&#xff08;1968年10月—2024年8月1日&#xff09;&#xff0c;中国人民大学哲学院杰出学者、特聘教授&#xff0c;美国德州州立大学客座教授&#xff0c;主要从事神经哲学、心灵哲…

大学生编程入门指南:如何从零开始?

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 编程语言选择 &#x1f4da; 1. Python 2. JavaScript 3. Java 4. C/C 如何选择适合自己的编程语言&a…

人工智能深度学习系列—探索余弦相似度损失:深度学习中的相似性度量神器

文章目录 1. 背景介绍2. Loss计算公式3. 使用场景4. 代码样例5. 总结 1. 背景介绍 在机器学习和模式识别领域&#xff0c;评估样本间的相似性是一项基本而关键的任务。余弦相似度损失&#xff08;Cosine Similarity Loss&#xff09;作为一种衡量向量间相似度的损失函数&#…

TPAMI 2024 | 全新框架!深度学习可解释度量学习!

TPAMI 2024 | 全新框架&#xff01;深度学习可解释度量学习&#xff01; DIML: Deep Interpretable Metric Learning via Structural Matching 题目&#xff1a;DIML: 通过结构匹配的深度可解释度量学习 作者&#xff1a;Wenliang Zhao, Yongming Rao, Jie Zhou , and Jiwen…

DedeCMS-V5.7.82-UTF8织梦管理系统漏洞

将靶场环境放到www目录下——访问/dedecms/uploads 安装程序 - 织梦内容管理系统 V5.7 UTF8SP2 同意协议——继续 继续 配置后——点击继续 进入后台 登录后台——填写用户名密码。 方法一&#xff1a;上传shell文件 后台——核心——附件管理——上传新文件。 访问/dedecms…

用车申请轻松搞定,智慧校园行政办公一站解决

智慧校园行政办公中的用车申请功能是为了解决校园内教师及工作人员出行需求而设计的一套数字化管理系统。作为智慧校园行政办公的一个重要模块&#xff0c;该功能旨在提高校园用车效率&#xff0c;简化申请流程&#xff0c;确保资源合理分配。 在用户提交在线用车申请之前&…

Win7虚拟机分享(已安装VMware Tools)

前言 之前写过VMware安装Win7并安装VMware tools的博客&#xff0c;但操作仍显繁琐。后来发现可以直接分享已经配置好的虚拟机&#xff0c;所有软件都是安装好的&#xff0c;解压即用。 一. VMware Win7虚拟机配置 已完成的配置和安装的软件 专业版Win7系统(已永久激活)VMware…

个人航班追踪和查看软件Jetlog

什么是 Jetlog &#xff1f; Jetlog 是一个自托管航班跟踪器和查看器&#xff0c;允许用户添加、跟踪和分析自己的航班&#xff0c;提供个性化和用户友好的方式来探索航班数据。 软件特点&#xff1a; &#x1f30d; 所有访问过的机场和航班轨迹的世界地图视图&#x1f4ca; 所…

关于技术资产建设

目录 现象 “技术资产”的概念 “技术资产”的意义 效率 质量 成本 “技术资产”的建设 二方库建设 二方库的概念 二方库的开发原则与思路 技术底座建 技术底座建设原则 技术底座的必要性 “技术资产”的演进思路 现象 先说一个经典案例&#xff1a;程序员小a长…

MySQL——数据表的基本操作(二)查看数据表

使用 SQL 语句创建好数据表后,可以通过查看数据表结构的定义,以确认数据表的定义是否正确。在 MySQL中,查看数据表的方式有两种,具体如下。 1、使用 SHOW CREATE TABLE 查看数据表 在 MySQL 中,SHOW CREATE TABLE语句不仅可以查看创建表时的定义语句还可以查看表的字符编码。S…

数据结构与算法 - 双端队列

1. 概述 双端队列、队列、栈对比 定义特点队列一端删除&#xff08;头&#xff09;&#xff0c;另一端添加&#xff08;尾&#xff09;First In First Out栈一端删除和添加&#xff08;顶&#xff09;Last In First Out双端队列两端都可以删除、添加优先级队列优先级高者先出…

Java整合腾讯云发送短信实战Demo

简介 在现代应用开发中&#xff0c;短信服务是非常重要的功能之一。它可以用于用户验证、通知等各种场景。本文将介绍如何使用Java整合腾讯云短信服务&#xff0c;并提供一个完整的实战示例代码。 环境准备 在开始之前&#xff0c;确保你已经完成以下准备工作&#xff1a; 注…