用数据库函数完成数据的增删改查
增:
将要存储的信息录入到结构体中,再使用snprintf函数信息结合sqlite3命令语句使用sqlite3_exec函数完成插入。
int do_insert(sqlite3 *ppDb)
{
Worker Work;
printf("输入插入的工号:");
scanf("%d",&Work.gh);
printf("输入插入的姓名:");
scanf("%s",Work.name);
printf("输入插入的薪资:");
scanf("%lf",&Work.salary);
char *errmsg = NULL;
char sqlite[100];
snprintf(sqlite,sizeof(sqlite),"insert into Work values(%d,\"%s\",%lf);",Work.gh,Work.name,Work.salary);
if(sqlite3_exec(ppDb,sqlite,NULL,NULL,&errmsg)!= 0)//实现插入一个工人信息
{
perror("sqlite3_exec");
printf("错误码:%d错误信息:%s,错误行:%d\n",sqlite3_errcode(ppDb),errmsg,__LINE__);
return -1;
}
return 0;
}
删:
根据输入的姓名来删除这个人的信息;原理和增操作一样,只需将snprintf函数中的字符串改成相应的sqlite3命令语句即可
int do_delete(sqlite3 *ppDb)
{
char key[20];
printf("输入要删除的姓名:");
scanf("%s",key);
getchar();
char *errmsg = NULL;
char sqlite[100];
snprintf(sqlite,sizeof(sqlite),"delete from Work where name == \"%s\";",key);
if(sqlite3_exec(ppDb,sqlite,NULL,NULL,&errmsg)!= 0)//实现输出工人信息
{
perror("sqlite3_exec");
printf("错误码:%d错误信息:%s,错误行:%d\n",sqlite3_errcode(ppDb),errmsg,__LINE__);
return -1;
}
printf("删除成功,输入5查看删除结果\n");
return 0;
}
改:
根据姓名更改相关信息,一次只能更改一项,所以使用了两次snprintf函数
int do_mod(sqlite3 *ppDb)
{
char key[20];
printf("输入要修改的姓名:");
scanf("%s",key);
getchar();
Worker Work;
printf("输入修改后的工号:");
scanf("%d",&Work.gh);
printf("输入修改后的薪资:");
scanf("%lf",&Work.salary);
char *errmsg = NULL;
char sqlite[100];
snprintf(sqlite,sizeof(sqlite),"update Work set gh = %d where name == \"%s\";",Work.gh,key);
if(sqlite3_exec(ppDb,sqlite,NULL,NULL,&errmsg)!= 0)//实现插入一个工人信息
{
perror("sqlite3_exec");
printf("错误码:%d错误信息:%s,错误行:%d\n",sqlite3_errcode(ppDb),errmsg,__LINE__);
return -1;
}
snprintf(sqlite,sizeof(sqlite),"update Work set salary = %lf where name == \"%s\";",Work.salary,key);
if(sqlite3_exec(ppDb,sqlite,NULL,NULL,&errmsg)!= 0)//实现插入一个工人信息
{
perror("sqlite3_exec");
printf("错误码:%d错误信息:%s,错误行:%d\n",sqlite3_errcode(ppDb),errmsg,__LINE__);
return -1;
}
printf("修改成功,输入5查看修改结果\n");
return 0;
}
查:
前面过程都类似,在sqlite3_exec函数中加入callback回调函数,实现输出查找的信息
int callback(void *arg,int n,char **msgtext,char **msgtable)
{
int i,j;
char **a = msgtable;
for(i = 0;i<2;i++)
{
for(j = 0;j<n;j++)
{
printf("%s\t",*(a++));
}
puts("");
}
return 0;
}
//查找一个工人的信息
int do_reseach(sqlite3 *ppDb)
{
char key[20];
printf("输入要查找的姓名:");
scanf("%s",key);
getchar();
char *errmsg = NULL;
char sqlite[100];
snprintf(sqlite,sizeof(sqlite),"select * from Work where name == \"%s\";",key);
if(sqlite3_exec(ppDb,sqlite,callback,NULL,&errmsg)!= 0)//实现查找一个工人信息
{
perror("sqlite3_exec");
printf("错误码:%d错误信息:%s,错误行:%d\n",sqlite3_errcode(ppDb),errmsg,__LINE__);
return -1;
}
return 0;
}
遍历:
和查找的操作类似,会出现一个问题:当我想把标题输出出来的时候,当输出完一个人的信息后这个标题又会重新输出一次。
这时想到可以在show_all中使用flag,这样就只能输出一次,但还是不行,还是会变;
又想到用static关键字,这样就不会改变flag了,但这样就只有第一次遍历可以有这个效果,后面就不会有列名;
既然static是将局部变量具有全局变量的效果,那就定义一个全局的flag变量
int show_all(void *arg,int n,char **msgtext,char **msgtable)
{
int num = 0;
for(int i = 0;i<n;i++)
{
printf("%s\t",*(msgtable+i));
}
puts("");
char **a = msgtext;
while(*a != NULL)
{
num++;
printf("%s\t",*(a++));
if(num%3 == 0)
{
printf("\n");
}
}
return 0;
}
//输出所以工人信息
int do_showall(sqlite3 *ppDb)
{
char *errmsg = NULL;
char sqlite[100] = "select * from Work;";
if(sqlite3_exec(ppDb,sqlite,show_all,NULL,&errmsg)!= 0)//实现查找一个工人信息
{
perror("sqlite3_exec");
printf("错误码:%d错误信息:%s,错误行:%d\n",sqlite3_errcode(ppDb),errmsg,__LINE__);
return -1;
}
}
定义全局变量后,如果在回调函数结束前将flag在重新改为1,那就白费功夫了,所以在do_showall函数结束前重新改为1.
int flag = 1;
int show_all(void *arg, int n, char **msgtext, char **msgtable)
{
int num = 0;
if (flag)
{
for (int i = 0; i < n; i++)
{
printf("%s\t", *(msgtable + i));
}
puts("");
flag = 0;
}
char **a = msgtext;
while (*a != NULL)
{
num++;
printf("%s\t", *(a++));
if (num % 3 == 0)
{
printf("\n");
}
}
return 0;
}
// 输出所以工人信息
int do_showall(sqlite3 *ppDb)
{
char *errmsg = NULL;
char sqlite[100] = "select * from Work;";
if (sqlite3_exec(ppDb, sqlite, show_all, NULL, &errmsg) != 0) // 实现查找一个工人信息
{
perror("sqlite3_exec");
printf("错误码:%d错误信息:%s,错误行:%d\n", sqlite3_errcode(ppDb), errmsg, __LINE__);
return -1;
}
flag = 1;
return 0;
}