SQLite库笔记:API函数编程

本文主要介绍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链接参数。编译示例如下:

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值