博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下基于SQLite3 实现商店商品管理系统
阅读量:3950 次
发布时间:2019-05-24

本文共 13552 字,大约阅读时间需要 45 分钟。

文章目录

水果店账单管理系统

一.SQLite相关C接口

如果第一次直接在命令行安装sqlite3,是不包含sqlite3.h这个包的,我们需要单独下载sqlite3支持的库,即通过命令行:

sudo apt install libsqlite3-dev

如果我们不知道该安装什么包来提供sqlite3的C/C++接口,可以通过debian官网通过查询软件包关键词可以知道库是依赖libsqlite3-dev包的。

注意,链接的时候要加上-lsqlite3表示依赖第三方库

关于创建一个数据库,可以通过create table stu (id integer, name text),但是如果连续创建的话会报错,因为已经存在了,所以我们可以使用create table if not exists stu (id integer, name text)来防止重复创建报错。

可以通过句柄来获取错误消息

重要接口

以下是重要的 C&C++ / SQLite 接口程序,基本可以您在 C/C++ 程序中使用 SQLite 数据库的需求。

序号 API & 描述
1 *sqlite3_open(const char *filename, sqlite3 *ppDb) 该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。如果 filename 参数是 NULL 或 ‘:memory:’,那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。如果文件名 filename 不为 NULL,那么 sqlite3_open() 将使用这个参数值尝试打开数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。
2 *sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char *errmsg) 该例程提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成。在这里,第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。
3 sqlite3_close(sqlite3*) 该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。

sqlite3_exec函数原型如下:

int sqlite3_exec(  sqlite3*,                                  /* 数据库句柄 */  const char *sql,                           /* 执行的SQLite命令 */  int (*callback)(void*,int,char**,char**),  /* Callback function */  void *,                                    /* 向回调函数传递的参数是 */  char **errmsg                              /* Error msg written here */);

sqlite3_exec()是一个通用函数,可以执行SQLite命令行,相当于间接使用命令行来操作数据库。

打开数据库

直接调用sqlite3_open()打开一个数据库。

检测返回值是否为SQLITE_OK,如果不是,表示出错了,出错信息的获取通过句柄可以获取,如下:

const char *sqlite3_errmsg(sqlite3*);

SQLite有31种返回值,如下:

#define SQLITE_OK           0   /* Successful result *//* beginning-of-error-codes */#define SQLITE_ERROR        1   /* Generic error */#define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */#define SQLITE_PERM         3   /* Access permission denied */#define SQLITE_ABORT        4   /* Callback routine requested an abort */#define SQLITE_BUSY         5   /* The database file is locked */#define SQLITE_LOCKED       6   /* A table in the database is locked */#define SQLITE_NOMEM        7   /* A malloc() failed */#define SQLITE_READONLY     8   /* Attempt to write a readonly database */#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */#define SQLITE_CORRUPT     11   /* The database disk image is malformed */#define SQLITE_NOTFOUND    12   /* Unknown opcode in sqlite3_file_control() */#define SQLITE_FULL        13   /* Insertion failed because database is full */#define SQLITE_CANTOPEN    14   /* Unable to open the database file */#define SQLITE_PROTOCOL    15   /* Database lock protocol error */#define SQLITE_EMPTY       16   /* Internal use only */#define SQLITE_SCHEMA      17   /* The database schema changed */#define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */#define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */#define SQLITE_MISMATCH    20   /* Data type mismatch */#define SQLITE_MISUSE      21   /* Library used incorrectly */#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */#define SQLITE_AUTH        23   /* Authorization denied */#define SQLITE_FORMAT      24   /* Not used */#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */#define SQLITE_NOTADB      26   /* File opened that is not a database file */#define SQLITE_NOTICE      27   /* Notifications from sqlite3_log() */#define SQLITE_WARNING     28   /* Warnings from sqlite3_log() */#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */#define SQLITE_DONE        101  /* sqlite3_step() has finished executing */

插入信息

基于sqlite3_exec()使用命令行语句来插入信息,根据上面所讲,插入的命令行如下:

2-- 插入一条记录	insert into stuinfo values(1001, 'zhangshangngsan', 18, 80);	insert into stuinfo (id, name, score) values(1002, 'lisi', 90);	可以按照全部元素的顺序插入,也可以指定元素插入	插入多条的时候直接在后面加上即可	insert into stuinfo (id, name, score) values(1002, 'lisi', 90), (1001, 'zhangshan', 18, 80);

先读取到要插入的信息,然后使用sprintf函数格式化为字符串,最后将字符串传递给sqlite3_exec()的第二个参数const char *sql来执行命令行操作数据库。

查询

查询有两种基础方法

  • 基于sqlite3_exec和回调函数,参考链接:https://sqlite.org/c3ref/exec.html
  • 直接使用sqlite3_get_table函数,参考链接:https://sqlite.org/c3ref/free_table.html

sqlite3_exec函数原型如下:

int sqlite3_exec(  sqlite3*,                                  /* 数据库句柄 */  const char *sql,                           /* 执行的SQLite命令 */  int (*callback)(void*,int,char**,char**),  /* Callback function */  void *,                                    /* 向回调函数传递的参数是 */  char **errmsg                              /* Error msg written here */);

sqlite3_exec()是一个通用函数,可以执行SQLite命令行,相当于间接使用命令行来操作数据库。

查询的结果通过回调函数反馈,有几行记录,就调用几次回调函数,所以每次回调函数的执行都是对一行信息的查询。

关于回调函数有如下说明:

  • 有几条记录就会调用几次回调函数
  • 回调函数的参数通过sqlite3_exec的第三个参数传递,给回调函数的第一个参数
  • 每条记录中有几列,就会传给第二个参数column
  • 第三个参数就是对应字段内容 char **value,以字符串的形式传递
  • 第四个参数char ** name就是字段名
  • 二级指针的用法和main函数的参数 char *argv[]一样
  • 回调函数返回的应该是0 表示正确,返回1代表出错

回调函数的定义可以如下:

static int callback(void *data, int argc, char **argv, char **azColName){
int i; for(i=0; i

还有,可以通过sqlite3_get_table来获取表信息,sqlite3_get_table 专门用于查询语句,不需要回调了:

int sqlite3_get_table(  sqlite3 *db,          /* 句柄 */  const char *zSql,     /* SQL to be evaluated */  char ***pazResult,    /* 获取的表信息,传递参数时直接一个二维数组的地址 */  int *pnRow,           /* 行数,包括数据名称 */  int *pnColumn,        /* 列数 */  char **pzErrmsg       /* 出错信息 */);

直接通过行数和列数来输出信息,不过要注意的是,返回到的查询信息,开始是表的数据名称,后面才是每个行的内容。

二.程序要求

假如我家开了个水果超市,有以下水果,想实现自动化管理,扫描二维码就能知道当前的水果状态,进货几天了,

好久需要再次进货,那些水果畅销,那些水果不畅销,那些水果春夏秋冬的价格波动,好,那么现在我想将
这些信息保存在数据库中,那么我应该怎么做;
提示: 建立一张fruit表,
假如水果有: 苹果,香蕉,梨,橘子,葡萄…(可以自己查一下英文保存到数据库)
水果价格: 苹果 5元/斤 香蕉 3元/斤 梨 3.5元/斤 橘子2.5元/斤 葡萄 8元/斤…
当前存货: 苹果 80斤 香蕉 200斤 梨 50斤 橘子300斤 葡萄 100斤…
超市每天水果都有进货和卖出嘛,水果的价格随着季节和天气也会有波动,顾客也会看一下每天水果的价格的嘛,
所以要求,根据上述提示,利用数据库完成水果店各种水果的增(进货)删(卖出)改(波动)查(看价格)功能。
并将进出货的时间和顾客光顾的时间记录到数据库中保存。

三.程序说明

题目要求:所以要求,根据上述提示,利用数据库完成水果店各种水果的增(进货)删(卖出)改(波动)查(看价格)功能。并将进出货的时间和顾客光顾的时间记录到数据库中保存。程序执行:直接make即可 显示界面,按照指示输入指令即可实现上述所有功能make clean用于清除二进制可执行文件程序说明:main函数中循环执行菜单栏目根据用户在菜单栏目中的输入跳转到相应的功能区执行,每项功能都封装在一个函数中功能区描述如下:	int menu(void);               //菜单	|	----void select_fruit(void);      //产看所有货物信息		void add_fruit(void);         //增加新货物信息		void delete_fruit(void);      //删除货物信息		void upadte_fruit(void);      //更新信息		|		----void purchase_control(void);  //进货			void sell_control(void);      //售卖			void price_change(void);      //价格变动			更新信息中可以进行:进货、售卖、价格变动等操作,也可退回上一菜单进货时间在进货、增加货物信息的时候更新顾客光顾时间在售卖的时候更新

四.实现代码

#include 
#include
#include
#include
#include
static int callback(void*,int,char**,char**);int menu(void); //菜单void select_fruit(void); //产看所有货物信息void add_fruit(void); //增加新货物信息void delete_fruit(void); //删除货物信息void upadte_fruit(void); //更新信息void purchase_control(void); //进货void sell_control(void); //售卖void price_change(void); //价格变动static char sql[128] = {
0};static sqlite3 *ppdb; //句柄static int ret;#define BUFLEN 255char tmpBuf[BUFLEN]; //时间字符串int main(int argc, const char *argv[]){
int n; //open the SQLite3 if (sqlite3_open("./fruit.db", &ppdb) != SQLITE_OK) {
printf("open filed:%s\n", sqlite3_errmsg(ppdb)); exit(1); } time_t t = time( 0 ); strftime(tmpBuf, BUFLEN, "%Y-%m-%d %H:%M", localtime(&t)); printf("%s\n\n\n", tmpBuf); //创建数据库,在系统初始化的时候使用一次 // memset(sql, 0, sizeof(sql)); // sprintf(sql, "create table fruit (name, price, stockpile, purchase_time, sell_time);"); // ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL); // if (ret != SQLITE_OK) {
// printf("create filed:%s\n", sqlite3_errmsg(ppdb)); // exit(1); // } while (1) {
n = menu(); switch (n) {
case 1: select_fruit(); break; case 2: add_fruit(); break; case 3: upadte_fruit(); //包括 进货、售出、价格修改 break; case 4: delete_fruit(); break; case 5: sqlite3_close(ppdb); exit(0); default: printf("wrong number!!!\n"); break; } } return 0;}int menu(void){
int n; printf("---- Welcome to GQ's Fruit commodity management system! ----\n"); printf("- (please input the number as follows) -\n"); printf("- 1.select all commodity -\n"); printf("- 2.add commodity -\n"); printf("- 3.upadte commodity -\n"); printf("- 4.delete commodity -\n"); printf("- 5.exit system -\n"); printf("------------------------------------------------------------\n"); printf("input number here:"); scanf("%d", &n); return n;}//查看所有货物信息void select_fruit(void){
memset(sql, 0, sizeof(sql)); sprintf(sql, "select * from fruit;"); ret = sqlite3_exec(ppdb, sql, callback, NULL, NULL); //useing callback function if (ret != SQLITE_OK) {
printf("select filed:%s\n", sqlite3_errmsg(ppdb)); exit(1); } printf("select ok!\n\n\n");}static int callback(void *data, int column_number, char *column_data[], char *column_name[]){
int i; for (i = 0; i < column_number; i++) {
if (i == column_number-1) printf("%13s=%7s ", column_name[i], column_data[i]); else printf("%13s=%9s , ", column_name[i], column_data[i]); } puts(""); return 0;}//完成添加新货物信息void add_fruit(void){
char name[10]; float price; int stockpile; printf("please input the fruit message:\n"); printf(" name price stockpile \n>"); scanf("%s", name); scanf("%f", &price); scanf("%d", &stockpile); getchar(); //吃掉回车 time_t t = time( 0 ); strftime(tmpBuf, BUFLEN, "%Y-%m-%d %H:%M", localtime(&t)); memset(sql, 0, sizeof(sql)); sprintf(sql, "insert into fruit values('%s', %f, %d, '%s', NULL);", name, price, stockpile, tmpBuf);//注意冒号 ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL); if (ret != SQLITE_OK) {
printf("add filed:%s\n", sqlite3_errmsg(ppdb)); exit(1); } printf("add success!\n\n\n");}//完成删除货物信息void delete_fruit(void){
char name[10]; printf("input delete fruit:"); scanf("%s", name); getchar(); memset(sql, 0, sizeof(sql)); sprintf(sql, "delete from fruit where name='%s';", name);//注意冒号 ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL); if (ret != SQLITE_OK) {
printf("delete filed:%s\n", sqlite3_errmsg(ppdb)); exit(1); } printf("delete %s success\n\n\n", name);}//完成进货、卖出、价格波动void upadte_fruit(void){
int n; printf("---- Welcome to GQ's Fruit commodity management system! ----\n"); printf("- (please input the number as follows) -\n"); printf("- 1.purchase control -\n"); printf("- 2.sell control -\n"); printf("- 3.price change -\n"); printf("- 4.last step -\n"); printf("- 5.exit system -\n"); printf("------------------------------------------------------------\n"); printf("input number here:"); scanf("%d", &n); switch (n) {
case 1: purchase_control(); break; case 2: sell_control(); break; case 3: price_change(); break; case 4: return ; break; case 5: sqlite3_close(ppdb); break; default: break; }}void purchase_control(void){
char name[10]; int stockpile; printf("input fruit name:"); scanf("%s", name); getchar(); printf("input purchase quantity:"); scanf("%d", &stockpile); getchar(); sprintf(sql, "update fruit set stockpile=%d where name='%s';", stockpile, name); ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL); if (ret != SQLITE_OK) {
printf("purchase_control filed:%s\n", sqlite3_errmsg(ppdb)); exit(1); } printf("purchase_control %s success\n\n\n", name);}void sell_control(void){
char name[10]; int stockpile; printf("input fruit name:"); scanf("%s", name); getchar(); printf("input new stockpile:"); scanf("%d", &stockpile); getchar(); time_t t = time( 0 ); strftime(tmpBuf, BUFLEN, "%Y-%m-%d %H:%M", localtime(&t)); sprintf(sql, "update fruit set stockpile=%d ,sell_time='%s' where name='%s';", stockpile, tmpBuf, name); ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL); if (ret != SQLITE_OK) {
printf("sell_control filed:%s\n", sqlite3_errmsg(ppdb)); exit(1); } printf("sell_control %s success\n\n\n", name);}void price_change(void){
char name[10]; float price; printf("input fruit name:"); scanf("%s", name); getchar(); printf("input new price:"); scanf("%f", &price); getchar(); sprintf(sql, "update fruit set price=%f where name='%s';", price, name); ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL); if (ret != SQLITE_OK) {
printf("price_change filed:%s\n", sqlite3_errmsg(ppdb)); exit(1); } printf("price_change %s success\n\n\n", name);}

转载地址:http://yxwzi.baihongyu.com/

你可能感兴趣的文章
避免Andriod平台图片失真的图片形式
查看>>
Android之Gridview图片列表
查看>>
objdump的使用方法
查看>>
编译错误处理noproguard.classes-with-local.dex已杀死
查看>>
LTE - CSFB技术
查看>>
GSM链路层信令协议
查看>>
技术道德
查看>>
“需求为王”才是根本
查看>>
高效率的危害
查看>>
寻找边缘性创新
查看>>
让创意瞄准市场
查看>>
高效经理人应具有的八个重要习惯
查看>>
优秀的领导者能读懂人才
查看>>
大智若愚也是领导力
查看>>
android如何编译MTK的模拟器
查看>>
android如何添加AP中要使用的第三方JAR文件
查看>>
利用sudo命令为Ubuntu分配管理权限
查看>>
Ubuntu下几个重要apt-get命令用法与加速UBUNTU
查看>>
Ubuntu中网页各种插件安装命令
查看>>
使用tar命令备份Ubuntu系统
查看>>