【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

目录

一、前言

正如题目所言,最近笔者需要完成一个 数据库嵌入式编程的任务,要求使用 C/C++编程语言,由于笔者用不习惯 Visual Studio系列软件,遂选用 DEV-CPP作为开发工具,由于之前没有相关经验,踩了许多坑,特此记录SQLite+DEV-CPP实现C/C++嵌入式编程操作数据库过程。

二、SQL介绍

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。SQLite 的一个重要的特性是零配置的,这意味着不需要复杂的安装或管理。

; 三、如何在 Windows 上安装 SQLite

3.1 下载预编译的二进制文件

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

; 3.2 添加环境变量

  • 添加 C:\sqlitePATH 环境变量。
    【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
  • 最后打开 cmd,使用 sqlite3命令,将显示如下结果。
    【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
    至此sqlite安装成功。

四、如何使用C/C++ API连接SQLite

基础的三个API如下表。

序号API1sqlite3_open(const char filename, sqlite3 ppDb)2sqlite3_exec(sqlite3, const char sql, sqlite_callback, void data, char *errmsg)3sqlite3_close(sqlite3)

  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 禁止关闭的错误消息。

但是我们要怎样使用DEVCPP链接到SQLite数据库呢?下一章将会详细描述。

五、使用DEVCPP链接SQLite数据库

5.1 编译静态SQLite3数据库文件

前文 3.2节中我们已经下载了 SQLite的预编译的二进制文件。
接下来我们编译sqlite3静态库。打开 DEV-CPP,新建一个静态链接库项目 sqlite_lib。我们把项目保存在一个我们事先建好的文件夹中,文件夹路径 C:\sqlite\sqlite_lib。如下图:

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

新建项目结束后,我们将源代码中的 sqlit3.h以及 sqlite3.c文件拷贝至 C:\sqlite\sqlite_lib文件夹内。如下图:

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

然后在 DEV-CPP中的项目上右键,添加 sqlite_lib文件夹内的两个名为 sqlite3文件。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

之后,我们点击编译按钮或者运行菜单中的编译菜单或者直接按F9,开始编译。可以看到编译成功,并生成了 sqlite_lib.a静态库。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

恭喜,至此距离链接成功已经仅差一次成功的测试了。

; 5.2 建立静态库的测试项目

测试官网给出的测试代码是否能正常编译并正常工作。我们在 DEV-CPP中新建一个控制台项目。项目保存在文件夹路径 C:\sqlite\sqlite_lib_demo。见下图:

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

我们将官网的示例代码粘贴到 main.c文件中。该代码的作用是打开 test.db数据库,如果没有该数据库,则创建一个新的。代码如下:

#include
#include
int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   rc = sqlite3_open("test.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      exit(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");
   }
   sqlite3_close(db);
}

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

同时,我们将 C:\sqlite\sqlite_lib文件夹中的 sqlite3.h以及刚生成的 sqlite_lib.a拷贝至 C:\sqlite\sqlite_lib_demo文件夹中。
这里注意拷贝文件的后缀,不要拷贝错了。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

注意:即使将静态链接库文件拷贝至 C:\sqlite\sqlite_lib_demo文件夹内,但是 DEV-CPP编译时不会自动将静态库链接到项目里,需要手动再做一步告诉DEV-CPP链接什么库到项目里。

需要:点击DEVCPP上 项目菜单, 项目属性。打开 项目选项窗口,切换到 参数标签。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

点击 加入库或者对象,选择上文拷贝过的 sqlite_lib.a,然后依次点击打开确定按钮。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

最后:我们来编译项目。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

嗯?弹出了一个错误。提示 没有sqlite3.h这个文件或目录
#include <sqlite3.h> </sqlite3.h>改为 #include "sqlite3.h"即可。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

再次点击运行,此时提示 &#x6253;&#x5F00;&#x6570;&#x636E;&#x5E93;&#x6210;&#x529F;

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

检查文件夹 C:\sqlite\sqlite_lib_demo,出现了 test数据库。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

&#x547C;~&#x7EC8;&#x4E8E;&#x6210;&#x4E86;&#x3002;

后续给出了一些嵌入式编程练习,笔者也写了一个 非常简单的交互式操作数据库的程序,仅为了测试。
&#x9898;&#x76EE;&#xFF1A;

  1. 创建一个数据库Test,里面增加一个表格Student(Sno int, Sname char(10), Ssex char(2), Sbirth date)。
  2. 编写一个C/C++程序,一个简单的界面,通过界面接口,向表中插入10条记录,通过接口实现对数据库的增删改查操作(举例就行)。

创建一个数据库Test,里面增加一个表格Student(Sno int, Sname char(10), Ssex char(2), Sbirth date)。
这里我们使用命令行进入C:\sqlite\sqlite_lib_demo文件架,使用命令创建一个表格并使用”.schema Student”查看该表详细信息。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
上面的命令将在当前目录下创建一个文件 testDB.db。该文件将被 SQLite 引擎用作数据库。如果您已经注意到 sqlite3 命令在成功创建数据库文件之后,将提供一个 sqlite> 提示符。一旦数据库被创建,您就可以使用 SQLite 的 .databases 命令来检查它是否在数据库列表中。
    cd C:\sqlite\sqlite_lib_demo
    sqlite3 Student.db
    CREATE TABLE Student(
        Sno INT PRIMARY KEY NOT NULL,
        Sname CHAR(10),
        Ssex CHAR(2),
        Sbirth DATE
    );
    .schema

编写一个C/C++程序,一个简单的界面,通过界面接口,向表中插入10条记录,通过接口实现对数据库的增删改查操作(举例就行)。
前文中我们已经使用 DEV-CPP连接到了 SQLite数据库,这里编写代码实现交互式操作SQLite数据库。
将如下代码拷贝至 main.c。通过界面接口向表中插入10条记录。

#include
#include
#include "sqlite3.h"

int haveInfo=0;

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   if(argc>0){
        for(i=0; i<argc; i++){
        int j;
        if(strlen(azColName[i])%2==0){
            for(j=0;j<strlen(azColName[i]) && \
                strlen(azColName[i])%2==0;j+=2){
                printf("%c%c",azColName[i][j],azColName[i][j+1]);
            }
        }
        else{
            for(j=0;j<strlen(azColName[i]);j++){
                printf("%c",azColName[i][j]);
            }
        }

        printf(" = ");

        char * arg = argv[i] ? argv[i] : "NULL";

        if(strlen(arg)%2==0){
            for(j=0;j<strlen(arg);j+=2){
                printf("%c%c",arg[j],arg[j+1]);
            }
        }
        else{
            for(j=0;j<strlen(arg);j++){
                printf("%c",arg[j]);
            }
        }
        printf("\n");

        }
        haveInfo=1;
   }
    return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;

   rc = sqlite3_open("Student.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
      exit(0);
   }else{
      fprintf(stderr, "Opened database successfully\n");

   }
    system("color 3");
    int func=99;
    while(1){
        if(func==99){
            printf("**********C语言连接sqlite数据操作***********\n" \
                    "1.查询\n" \
                    "2.插入\n" \
                    "3.删除\n" \
                    "4.修改\n" \
                    "5.查询Course表\n"\
                    "6.查询某个学生选修某一门课程的选课信息\n"\
                    "0.退出\n" \
                    "*********C语言连接sqlite数据操作***********\n" \
                    "请选择你需要的操作: ");
        }

        scanf("%d",&func);
        if(func!=0 && func!=1 && func!=2 && func!=3 && func!=4 && func!=5 && func!=6){
            func=99;
        }

        if(func==1){

            int num=-1;
            while(num==-1){
                printf("请输入查询表Student中的记录次数:");
                scanf("%d",&num);
            }
            int i;
            for(i=0;i<num;i++){
                printf("输入查询表Student中的记录的学号," \
                        "仅支持学号查询,例002:\n");

                int Sno;
                char SQL[500];

                scanf("%d",&Sno);

                snprintf(SQL, 500, "SELECT * FROM Student WHERE Sno=%d;",Sno);

               rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
               if( rc != SQLITE_OK ){
                    fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);
                    sqlite3_free(zErrMsg);
               }else{
                    if(haveInfo){
                        fprintf(stdout, "查询成功,信息如上↑\n");
                        haveInfo=0;
                       }
                    else{
                        fprintf(stdout, "查询成功,未查询到相关信息\n");
                    }
               }

            }
            printf("执行完毕,进入主菜单\n");
            func=99;

        }

        if(func==2){

            int num=-1;
            while(num==-1){
                printf("请输入插入至表Student中的记录条数(仅限数字):");
                scanf("%d",&num);
            }
            int i;
            for(i=0;i<num;i++){
                printf("请按格式输入插入的每一条记录内容,格式:学号 姓名 "\
                        "性别 生日,例\"001 贾明一 男 2000-10-10\"\n");

                int Sno;
                char Sname[10],Ssex[2],Sbirth[50];
                char SQL[500];

                scanf("%d %s %s %s",&Sno,&Sname,&Ssex,&Sbirth);

                snprintf(SQL, 500, "INSERT INTO Student VALUES(%d,'%s','%s','%s');"\
                    ,Sno,Sname,Ssex,Sbirth);

               rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
               if( rc != SQLITE_OK ){
                  fprintf(stderr, "插入失败SQL error: %s\n", zErrMsg);
                  sqlite3_free(zErrMsg);
               }else{
                  fprintf(stdout, "记录创建成功 \n");
               }

            }
            printf("执行完毕,进入主菜单\n");
            func=99;

        }

        if(func==3){

            int num=-1;
            while(num==-1){
                printf("请输入删除表Student中的记录次数:");
                scanf("%d",&num);
            }
            int i;
            for(i=0;i<num;i++){
                printf("输入删除表Student中的记录的学号,仅支持学号删除,例002:\n");

                int Sno;
                char SQL[500];

                scanf("%d",&Sno);

                snprintf(SQL, 500, "DELETE FROM Student WHERE Sno=%d;",Sno);

               rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
               if( rc != SQLITE_OK ){
                  fprintf(stderr, "删除失败,SQL error: %s\n", zErrMsg);
                  sqlite3_free(zErrMsg);
               }else{
                  fprintf(stdout, "删除成功\n");
               }

            }
            printf("执行完毕,进入主菜单\n");
            func=99;

        }

        if(func==4){

            int num=-1;
            while(num==-1){
                printf("请输入修改表Student中的记录条数(仅限数字):");
                scanf("%d",&num);
            }
            int i;
            for(i=0;i<num;i++){
                printf("请按输入需要修改的记录学号,格式:修改的学号,例\"001\" \n");

                int Sno;
                char Sname[10],Ssex[2],Sbirth[50];
                char SQL[500];

                scanf("%d",&Sno);

                snprintf(SQL, 500, "SELECT * FROM Student WHERE Sno=%d;",Sno);

               rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
               if( rc != SQLITE_OK ){
                    fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);
                    sqlite3_free(zErrMsg);
               }else{
                    if(haveInfo){
                        fprintf(stdout, "查询成功,信息如上↑\n");
                        haveInfo=0;
                       }
                    else{
                        fprintf(stdout, "查询成功,未查询到相关信息\n");
                    }
               }

                printf("请按输入新的记录内容,格式:学号 姓名 性别 生日"\
                    ",例\"001 辛明子 男 2000-10-10\"\n");

                scanf("%d %s %s %s",&Sno,&Sname,&Ssex,&Sbirth);

                snprintf(SQL, 500, "UPDATE Student SET Sno=%d, Sname='%s'"\
                    ", Ssex='%s', Sbirth='%s' WHERE Sno = %d;",Sno,Sname,Ssex,Sbirth,Sno);

               rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
               if( rc != SQLITE_OK ){
                  fprintf(stderr, "修改失败SQL error: %s\n", zErrMsg);
                  sqlite3_free(zErrMsg);
               }else{
                  fprintf(stdout, "记录修改成功 \n");
               }

            }
            printf("执行完毕,进入主菜单\n");
            func=99;

        }

        if(func==5){

            int num=-1;
            while(num==-1){
                printf("请输入查询表Course中的记录次数:");
                scanf("%d",&num);
            }
            int i;
            for(i=0;i<num;i++){
                printf("输入查询表Course中的记录的课程号," \
                        "仅支持课程号查询,例002:\n");

                int Cno;
                char SQL[500];

                scanf("%d",&Cno);

                snprintf(SQL, 500, "SELECT * FROM Course WHERE Cno=%d;",Cno);

               rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
               if( rc != SQLITE_OK ){
                    fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);
                    sqlite3_free(zErrMsg);
               }else{
                    if(haveInfo){
                        fprintf(stdout, "查询成功,信息如上↑\n");
                        haveInfo=0;
                       }
                    else{
                        fprintf(stdout, "查询成功,未查询到相关信息\n");
                    }
               }

            }
            printf("执行完毕,进入主菜单\n");
            func=99;

        }

        if(func==6){

            int num=-1;
            while(num==-1){
                printf("请输入查询某个学生选修某一门课程的选课信息次数:");
                scanf("%d",&num);
            }
            int i;
            for(i=0;i<num;i++){
                printf("要查询的学号和课程号,例002 002:\n");

                int Sno,Cno;
                char SQL[500];

                scanf("%d %d",&Sno,&Cno);

                snprintf(SQL, 500, "SELECT Sno,Cname,Grade FROM Course,SC WHERE Course.Cno=SC.Cno AND SC.Cno=%d AND SC.Sno=%d;",Cno,Sno);

                rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
                if( rc != SQLITE_OK ){
                    fprintf(stderr, "查询失败,SQL error: %s\n", zErrMsg);
                    sqlite3_free(zErrMsg);
                }else{
                    if(haveInfo){
                        fprintf(stdout, "查询成功,信息如上↑\n");
                        haveInfo=0;

                        int funcc=-1;
                        while(funcc==-1){
                            printf("是否对该生该课程的成绩进行修改,键入1代表修改,键入0代表不修改\n");
                            scanf("%d",&funcc);
                        }
                        if(funcc==1){
                            printf("请输入新的成绩\n");
                            scanf("%d",&funcc);
                        }

                        snprintf(SQL, 500, "UPDATE SC SET Grade=%d WHERE Cno=%d AND Sno=%d;",funcc,Cno,Sno);

                        rc = sqlite3_exec(db, SQL, callback, 0, &zErrMsg);
                        if( rc != SQLITE_OK ){
                            fprintf(stderr, "更新失败,SQL error: %s\n", zErrMsg);
                            sqlite3_free(zErrMsg);
                        }else{
                                fprintf(stdout, "更新成功\n");
                        }

                    }
                    else{
                        fprintf(stdout, "查询成功,未查询到相关信息\n");
                    }
                }

            }
            printf("执行完毕,进入主菜单\n");
            func=99;

        }

        if(func==0){
            break;
        }

    }

   sqlite3_close(db);
   return 0;
}

以下截图代表交互式 插入十条数据。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
插入结束,查看数据库,信息插入成功。
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
以下截图交互式 增加一条数据进入数据库中。
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

以下截图交互式删除一条数据进入数据库中。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

以下截图交互式 修改一条数据进入数据库中。

【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库
以下截图交互式 查询一条数据于数据库中。
【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

六、总结

以上就是今天要讲的内容,本文介绍了如何在Windows10系统下,安装SQLite,并使用DEV-CPP编译链接到SQLite,使用SQLite提供的C/C++的API进行嵌入式编程来操作数据库。
本文提供了简单的程序以嵌入式编程的方式来操作数据库,但仅涉及到增删改查,更为高级的数据库操作带读者进一步开发。

七、参考

SQLite官网:https://www.sqlite.org/index.html
菜鸟教程:https://www.runoob.com/sqlite/sqlite-tutorial.html

Original: https://blog.csdn.net/tangjiahao10/article/details/125152888
Author: TangPlusHPC
Title: 【数据库】“SQLite”+“DEV-CPP”实现C/C++嵌入式编程操作数据库

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/816049/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球