数据库sqlite3

用数据库函数完成数据的增删改查

增:

将要存储的信息录入到结构体中,再使用snprintf函数信息结合sqlite3命令语句使用sqlite3_exec函数完成插入。

cs 复制代码
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命令语句即可

cs 复制代码
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函数

cs 复制代码
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回调函数,实现输出查找的信息

cs 复制代码
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变量

cs 复制代码
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.

cs 复制代码
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;
}
相关推荐
野犬寒鸦几秒前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL1 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·1 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德1 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫1 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i2 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.2 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn2 小时前
【Redis】渐进式遍历
数据库·redis·缓存
橙露2 小时前
Spring Boot 核心原理:自动配置机制与自定义 Starter 开发
java·数据库·spring boot
冰暮流星2 小时前
sql语言之分组语句group by
java·数据库·sql