本地数据库 sqlite3 编译和使用

简介: 本地数据库 sqlite3 编译和使用

本地数据库 sqlite3 编译和使用

sqlite3

下载、编译、安装

下载

linux 环境下编译、安装

C/C++ 使用示例

sqlite3 C/C++ 接口

数据库创建/打开操作

数据库正常操作

创建表

删除表

插入语句

查询语句

条件查询语句

运算语句

更新语句

删除语句

关闭数据库操作

代码工程使用

添加 sqlite 库文件到工程下

修改 Cmake 配置文件

工程中代码使用

sqlite3

SQLite是一个C语言库,它实现了一个小型、快速、自包含、高可靠性、功能齐全的SQL数据库引擎。


SQLite是世界上使用最多的数据库引擎。SQLite内置于所有手机和大多数计算机中,并捆绑在人们每天使用的无数其他应用程序中。更多信息。。。


SQLite文件格式稳定、跨平台、向后兼容,开发人员承诺在2050年保持这种格式。SQLite数据库文件通常用作容器,在系统之间传输丰富的内容,并作为数据的长期存档格式[4]。目前有超过1万亿(1e12)个SQLite数据库在使用[5]。


SQLite源代码属于公共领域,每个人都可以自由地用于任何目的。


下载、编译、安装

下载

可以去 sqlite 官方网站:官方网站 找到下载版本进行下载,也可以直接点击这里提供的 下载链接(sqlite-snapshot-202108231028.tar)


linux 环境下编译、安装

将下载后的压缩包在 linux 操作系统环境下进行解压:


$ tar -xvf sqlite-snapshot-202108231028.tar.gz 
# 这里由于我需要 32 位的静态库,所以添加了 --enable-static 和 CC="gcc -m32" 参数
$ ../configure --enable-static --prefix=/home/ww/ww/gitlabproject/opcodetester/third/sqlite/ CC="gcc -m32"
$ make && make install


编译安装完成后,得到如下目录:

71dca1e144fd43028174c142590530c6.png

C/C++ 使用示例

使用 sqlite3 的整个过程其实和操作 MySQL 等数据库的方式是相同的,需要先创建或者打开本地数据库,然后就是通过数据库操作语法实现数据库的增删改查操作了。


sqlite3 C/C++ 接口

数据库创建/打开操作

首先,必须了解 sqlite3 的打开/创建数据库接口,具体使用方式参考如下代码:


sqlite3 *sql = NULL; // 一个打开的数据库实例
    const char * path = "test.db";//某个sql文件的路径
    // 根据文件路径打开数据库连接。如果数据库不存在,则创建。
    // 数据库文件的路径必须以C字符串传入。
    int result = sqlite3_open_v2(path, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
    // int result = sqlite3_open(path, &sql);
    if (result == SQLITE_OK) {
        std::cout << "打开数据库连接成功" << endl;;
    }
    else {
        std::cout << "打开数据库连接失败" << endl;
    }


通过函数 sqlite3_open_v2() 能够创建并且打开本地数据库,第一个参数是本地数据库的路径文件名。具体接口的声明如下:


SQLITE_API int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
SQLITE_API int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
SQLITE_API int sqlite3_open_v2(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb,         /* OUT: SQLite db handle */
  int flags,              /* Flags */
  const char *zVfs        /* Name of VFS module to use */
);


数据库正常操作

通过打开数据库操作 sqlite3_open() 获得了 ppDb 的数据库对象(句柄),接下来就是将组织好的数据库操作语言使用接口函数对数据库进行操作


相关接口的具体声明如下:


SQLITE_API int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare_v2(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare_v3(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare16(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare16_v2(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);
SQLITE_API int sqlite3_prepare16_v3(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nByte,              /* Maximum length of zSql in bytes. */
  unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);


使用的参考代码如下:


const char *sqlSentence = "INSERT INTO t_person(name, age) VALUES('夏明', 22); ";        //SQL语句
    sqlite3_stmt *stmt = NULL;        //stmt语句句柄
  //进行插入前的准备工作——检查语句合法性
    //-1代表系统会自动计算SQL语句的长度
    result = sqlite3_prepare_v2(sql, sqlSentence, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        std::clog<< "添加数据语句OK";
        //执行该语句
        sqlite3_step(stmt);
    }
    else {
        std::clog << "添加数据语句有问题";
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);


其中,在开始的部分需要首先拼好一个 SQL 语句,这里使用的语句为:

INSERT INTO t_person(name, age) VALUES('夏明', 22); 表示向 t_person 表中插入数据 name='夏明', age=22 的数据。如果是新创建的空白数据库,注意需要先创建数据表才能开始进行数据的增删改查啊。


知道了如何通过 SQL 语句实现对数据库的操作后,我们来看一下 SQL 语句的使用。(这里,可以参考菜鸟学堂进行的总结:sqlite3 菜鸟教程)


创建表

语法


CREATE TABLE 语句的基本语法如下:


CREATE TABLE database_name.table_name(
   column1 datatype  PRIMARY KEY(one or more columns),
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
);


CREATE TABLE 是告诉数据库系统创建一个新表的关键字。CREATE TABLE 语句后跟着表的唯一的名称或标识。您也可以选择指定带有 table_name 的 database_name。


实例


下面是一个实例,它创建了一个 COMPANY 表,ID 作为主键,NOT NULL 的约束表示在表中创建纪录时这些字段不能为 NULL:


sqlite> CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);


下面是一个实例,它创建了一个 COMPANY 表,ID 作为主键,NOT NULL 的约束表示在表中创建纪录时这些字段不能为 NULL:


sqlite> CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);


C/C++ 中使用


const char *sqlCreatetable = "CREATE TABLE t_person(name TEXT PRIMARY KEY NOT NULL, age INTEGER);";
    sqlite3_stmt *stmt = NULL;        //stmt语句句柄
    result = sqlite3_prepare_v2(sql, sqlCreatetable, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        std::clog<< "创建数据表成功" << endl;
        //执行该语句
        sqlite3_step(stmt);
    }
    else {
        std::clog << "创建数据表失败" << endl;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);


删除表

SQLite 的 DROP TABLE 语句用来删除表定义及其所有相关数据、索引、触发器、约束和该表的权限规范。( 使用此命令时要特别注意,因为一旦一个表被删除,表中所有信息也将永远丢失。)


语法


DROP TABLE 语句的基本语法如下。您可以选择指定带有表名的数据库名称,如下所示:


DROP TABLE database_name.table_name;


实例


让我们先确认 COMPANY 表已经存在,然后我们将其从数据库中删除。


sqlite>.tables
COMPANY       test.COMPANY


这意味着 COMPANY 表已存在数据库中,接下来让我们把它从数据库中删除,如下:


sqlite>DROP TABLE COMPANY;
sqlite>


现在,如果尝试 .TABLES 命令,那么将无法找到 COMPANY 表了:


sqlite>.tables
sqlite>


显示结果为空,意味着已经成功从数据库删除表。


C/C++ 中使用


 

const char *sqlCreatetable = "DROP  TABLE  t_person;";
    sqlite3_stmt *stmt = NULL;        //stmt语句句柄
    result = sqlite3_prepare_v2(sql, sqlCreatetable, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        std::clog<< "删除数据表成功" << endl;
        //执行该语句
        sqlite3_step(stmt);
    }
    else {
        std::clog << "删除数据表失败" << endl;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);


插入语句

SQLite 的 INSERT INTO 语句用于向数据库的某个表中添加新的数据行。(这个表一定要先创建出来才可以正常执行插入数据)


语法


INSERT INTO 语句有两种基本语法,如下所示:


INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]  
VALUES (value1, value2, value3,...valueN);


在这里,column1, column2,…columnN 是要插入数据的表中的列的名称。


如果要为表中的所有列添加值,您也可以不需要在 SQLite 查询中指定列名称。但要确保值的顺序与列在表中的顺序一致。SQLite 的 INSERT INTO 语法如下:


INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);


实例


假设您已经在 testDB.db 中创建了 COMPANY表,如下所示:


sqlite> CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);


现在,下面的语句将在 COMPANY 表中创建六个记录:


INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Allen', 25, 'Texas', 15000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (5, 'David', 27, 'Texas', 85000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );


您也可以使用第二种语法在 COMPANY 表中创建一个记录,如下所示:


INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );


上面的所有语句将在 COMPANY 表中创建下列记录。下一章会教您如何从一个表中显示所有这些记录。


ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0
6           Kim         22          South-Hall  45000.0
7           James       24          Houston     10000.0


使用一个表来填充另一个表


您可以通过在一个有一组字段的表上使用 select 语句,填充数据到另一个表中。下面是语法:


INSERT INTO first_table_name [(column1, column2, ... columnN)] 
   SELECT column1, column2, ...columnN 
   FROM second_table_name
   [WHERE condition];


C/C++ 中使用


const char *sqlSentence = "INSERT INTO t_person(name, age) VALUES('夏明', 22); ";        //SQL语句
    //进行插入前的准备工作——检查语句合法性
    //-1代表系统会自动计算SQL语句的长度
    result = sqlite3_prepare_v2(sql, sqlSentence, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        std::clog<< "添加数据语句OK" << endl;
        //执行该语句
        sqlite3_step(stmt);
    }
    else {
        std::clog << "添加数据语句有问题" << endl;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);


查询语句

SQLite 的 SELECT 语句用于从 SQLite 数据库表中获取数据,以结果表的形式返回数据。这些结果表也被称为结果集。


语法


SQLite 的 SELECT 语句的基本语法如下:


SELECT column1, column2, columnN FROM table_name;


在这里,column1, column2…是表的字段,他们的值即是您要获取的。如果您想获取所有可用的字段,那么可以使用下面的语法:


SELECT * FROM table_name;


实例


假设 COMPANY 表有以下记录:


ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0
6           Kim         22          South-Hall  45000.0
7           James       24          Houston     10000.0


下面是一个实例,使用 SELECT 语句获取并显示所有这些记录。在这里,前两个个命令被用来设置正确格式化的输出。


sqlite>.header on
sqlite>.mode column
sqlite> SELECT * FROM COMPANY;


最后,将得到以下的结果:


ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0
6           Kim         22          South-Hall  45000.0
7           James       24          Houston     10000.0


如果只想获取 COMPANY 表中指定的字段,则使用下面的查询:


sqlite> SELECT ID, NAME, SALARY FROM COMPANY;


上面的查询会产生以下结果:


ID          NAME        SALARY
----------  ----------  ----------
1           Paul        20000.0
2           Allen       15000.0
3           Teddy       20000.0
4           Mark        65000.0
5           David       85000.0
6           Kim         45000.0
7           James       10000.0


设置输出列的宽度


有时,由于要显示的列的默认宽度导致 .mode column,这种情况下,输出被截断。此时,您可以使用 .width num, num… 命令设置显示列的宽度,如下所示:


sqlite>.width 10, 20, 10
sqlite>SELECT * FROM COMPANY;


上面的 .width 命令设置第一列的宽度为 10,第二列的宽度为 20,第三列的宽度为 10。因此上述 SELECT 语句将得到以下结果:


ID          NAME                  AGE         ADDRESS     SALARY
----------  --------------------  ----------  ----------  ----------
1           Paul                  32          California  20000.0
2           Allen                 25          Texas       15000.0
3           Teddy                 23          Norway      20000.0
4           Mark                  25          Rich-Mond   65000.0
5           David                 27          Texas       85000.0
6           Kim                   22          South-Hall  45000.0
7           James                 24          Houston     10000.0


Schema 信息


因为所有的点命令只在 SQLite 提示符中可用,所以当您进行带有 SQLite 的编程时,您要使用下面的带有 sqlite_master 表的 SELECT 语句来列出所有在数据库中创建的表:


sqlite> SELECT tbl_name FROM sqlite_master WHERE type = 'table';


假设在 testDB.db 中已经存在唯一的 COMPANY 表,则将产生以下结果:


tbl_name
----------
COMPANY


您可以列出关于 COMPANY 表的完整信息,如下所示:


sqlite> SELECT sql FROM sqlite_master WHERE type = 'table' AND tbl_name = 'COMPANY';


假设在 testDB.db 中已经存在唯一的 COMPANY 表,则将产生以下结果:


CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
)


C/C++ 中使用

result = sqlite3_prepare_v2(sql, sqlSentence1, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        std::clog <<  "查询语句OK";
            // 每调一次sqlite3_step()函数,stmt语句句柄就会指向下一条记录
            while (sqlite3_step(stmt) == SQLITE_ROW) {
                // 取出第0列字段的值
                const unsigned char *name = sqlite3_column_text(stmt, 0);
                // 取出第1列字段的值
                int age = sqlite3_column_int(stmt, 1);
                //输出相关查询的数据
                std::clog << "name = " << name <<", age = "<< age << endl;
            }
    }
    else {
        std::clog << "查询语句有问题" << endl;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);


条件查询语句


运算语句


更新语句


删除语句


关闭数据库操作

在使用完成数据库后,最好正常关闭数据库,而 C/C++ 中关闭数据库的操作接口如下:


SQLITE_API int sqlite3_close(sqlite3*);
SQLITE_API int sqlite3_close_v2(sqlite3*);


代码中操作如下:


if (sql) 
    {
        sqlite3_close_v2(sql);
        sql = nullptr;
    }


代码工程使用

添加 sqlite 库文件到工程下

在工程目录 third 下创建 sqlite 库相关文件存放的目录路径 third/sqlite ,如下:

408241814de64d37acddb109fa97692d.png

修改 Cmake 配置文件

# sqlite3
set(SQLITELIB_PATH ${PROJECT_SOURCE_DIR}/third/sqlite)
list(APPEND SQLITE_LIBS_INCLUDE ${SQLITELIB_PATH}/include)
list(APPEND SQLITE_LIBS_INCLUDE ${SQLITELIB_PATH}/include/log4c)
link_directories(${SQLITELIB_PATH}/lib)
link_libraries(sqlite3)
...
#添加头文件引用路径
target_include_directories(opcodetester PUBLIC
                           ${PROJECT_BINARY_DIR}
                           ${EXTRA_INCLUDE}
                           ${SQLITE_LIBS_INCLUDE }
            )


工程中代码使用

这里首先是在一个测试程序中用到了数据库(针对X86 opcode 指令集测试),所以将设计如下的数据表内容:


数据名称 类型 含义

instruction 字符类型 【助记符名称】测试指令对应的助记符名称,例如 “ADD” “SUB” “CMP” 等

opcode 字节类型 【opcode】这条指令对应的 opcode ,Opcode 可能存在不止一个字节,所以这里需要存放一组字节数据

true_result 数据类型 REAL 【正确执行结果】该指令在 X86 机器上运行的计算结果,作为测试结果是否正确的评定标准

param1 数据类型 REAL 参数1 该指令在使用时所需的参数1

param2 数据类型 REAL 参数1 该指令在使用时所需的参数2

param3 数据类型 REAL 参数1 该指令在使用时所需的参数3

param4 数据类型 REAL 参数1 该指令在使用时所需的参数4

创建数据库和构造的相关代码如下:


#ifndef     _COMMON_DATABASE__H
#define     _COMMON_DATABASE__H
#include "sqlite3.h"
#include "base.hpp"
#include "debug.hpp"
class Database
{
private:
    sqlite3         *sql;
    sqlite3_stmt    *stmt;
    char            *mydbfilename;
public:
    Database(const char *dbfilename = "test.db");
    ~Database();
    int insert(const char *ins, const char *op, double *result);
    int selectIns(const char *ins, const char *opcode, double* &result);
private:
    int myDataOpen(const char *dbfilename);
    bool myDataClose(void);
    bool myDataCreateTable(void);
    bool myDataDropTable(void);
    bool myDataInsetData(const char *instruction, const char *opcode, double *true_reslut);
    bool myDataSelectData(void);
};
int Database::selectIns(const char *ins, const char *opcode, double* &result)
{
    int ret = 0;
    const char *sqlSentence1 = "SELECT * FROM t_opcode WHERE instruction == '%s' AND  opcode == '%s';";    //SQL语句
    char select_buf[1024] = {0};
    sprintf(select_buf, sqlSentence1, ins, opcode);
    //进行查询前的准备工作——检查语句合法性
    //-1代表系统会自动计算SQL语句的长度
    ret = sqlite3_prepare_v2(sql, select_buf, -1, &stmt, NULL);
    if (ret == SQLITE_OK) {
        Log.INFO("查询语句OK");
        // 每调一次sqlite3_step()函数,stmt语句句柄就会指向下一条记录
        while (sqlite3_step(stmt) == SQLITE_ROW) 
        {
            result[0] = sqlite3_column_double(stmt, 2);
            result[1] = sqlite3_column_double(stmt, 3);
            result[2] = sqlite3_column_double(stmt, 4);
            result[3] = sqlite3_column_double(stmt, 5);
        }
    }
    else {
        Log.INFO("查询语句有问题");
        return -1;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);
    return 0;
}
int Database::insert(const char *ins, const char *op, double *result)
{
    myDataInsetData(ins, op, result);
    return 0;
}
bool Database::myDataSelectData(void)
{
    int result = 0;
    const char *sqlSentence1 = "SELECT * FROM t_opcode WHERE age < 30;";    //SQL语句
    std::string tmp;
    char buf[1024] = {0};
    //进行查询前的准备工作——检查语句合法性
    //-1代表系统会自动计算SQL语句的长度
    result = sqlite3_prepare_v2(sql, sqlSentence1, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        Log.INFO("查询语句OK");
        // 每调一次sqlite3_step()函数,stmt语句句柄就会指向下一条记录
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            // 取出第0列字段的值
            const unsigned char *Instruction = sqlite3_column_text(stmt, 0);
            // 取出第1列字段的值
            const unsigned char *opcode = sqlite3_column_text(stmt, 1);
            float true_result0 = sqlite3_column_double(stmt, 2);
            float true_result1 = sqlite3_column_double(stmt, 2);
            float true_result2 = sqlite3_column_double(stmt, 2);
            float true_result3 = sqlite3_column_double(stmt, 2);
            //输出相关查询的数据
            sprintf(buf, "Instruction = [%s], opcode = [%s] true_result = %f - %f - %f - %f ", \
                        Instruction, opcode, true_result0, true_result1, true_result2, true_result3);
            tmp = std::string(buf);
            Log.INFO(tmp);
        }
    }
    else {
        Log.INFO("查询语句有问题");
        return false;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);
    return true;
}
bool Database::myDataInsetData(const char *instruction, const char *opcode, double *true_reslut)
{
    int result = 0;
    const char *sqlSentence = \
        "INSERT INTO t_opcode(instruction, opcode, true_result0, true_result1, true_result2, true_result3) VALUES ('%s', '%s', %f, %f, %f, %f);";        //SQL语句
    char insert_buf[1024] = {0};
    sprintf(insert_buf, sqlSentence, instruction, opcode, true_reslut[0], true_reslut[1], true_reslut[2], true_reslut[3]);
    //进行插入前的准备工作——检查语句合法性
    //-1代表系统会自动计算SQL语句的长度
    result = sqlite3_prepare_v2(sql, insert_buf, -1, &stmt, NULL);
    if (result == SQLITE_OK) 
    {
        Log.INFO("添加数据语句OK");
        //执行该语句
        sqlite3_step(stmt);
    }
    else 
    {
        Log.INFO("添加数据语句有问题");
        return false;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);
    return true;
}
bool Database::myDataDropTable()
{
    int result = 0;
    const char *sqlCreatetable = "DROP  TABLE  t_opcode;";
    sqlite3_stmt *stmt = NULL;        //stmt语句句柄
    result = sqlite3_prepare_v2(sql, sqlCreatetable, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        Log.INFO("删除数据表成功");
        //执行该语句
        sqlite3_step(stmt);
    }
    else {
        Log.INFO("删除数据表失败");
        return false;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);
    return true;
}
bool Database::myDataCreateTable()
{
    int result = 0;
    /*
    instruction     指令助记符
    opcode          二进制opcode
    true_result0     保存计算结果
    true_result1     保存计算结果
    true_result2     保存计算结果
    true_result3     保存计算结果
    param1          计算参数。。。
    param2
    param3
    param4
    */
    const char *sqlCreatetable = 
        "CREATE TABLE t_opcode(\
            instruction TEXT PRIMARY KEY NOT NULL,\
            opcode TEXT,\
            true_result0  REAL,\
            true_result1  REAL,\
            true_result2  REAL,\
            true_result3  REAL,\
            param1 REAL,\
            param2 REAL,\
            param3 REAL,\
            param4 REAL);";
    result = sqlite3_prepare_v2(sql, sqlCreatetable, -1, &stmt, NULL);
    if (result == SQLITE_OK) {
        Log.INFO("创建数据表成功");
        //执行该语句
        sqlite3_step(stmt);
    }
    else {
        Log.INFO("创建数据表失败");
        return false;
    }
    //清理语句句柄,准备执行下一个语句
    sqlite3_finalize(stmt);
    return true;
}
bool Database::myDataClose()
{
    if(!sql)
    {
        return false;
    }
    sqlite3_close_v2(sql);
    sql = NULL;
    return true;
}
int Database::myDataOpen(const char *dbfilename)
{
    int ret = 0;
    int result = 0;
    /* 判断数据库文件是否存在, 不存在则创建,存在则仅打开 */
    if(!access(dbfilename, F_OK))
    {
        //文件存在
        result = sqlite3_open_v2(dbfilename, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
    }
    else
    {
        result = sqlite3_open_v2(dbfilename, &sql, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
        ret = 1;
    }
    if (result != SQLITE_OK) {
        Log.INFO("打开数据库连接失败");
        return -1;
    }
    Log.INFO("打开数据库连接成功");
    return ret;
}
Database::Database(const char *dbfilename)
{
    int ret = 0;
    sql = NULL;
    stmt = NULL;
    mydbfilename = strdup(dbfilename);
    if(!mydbfilename)
    {
        Log.INFO("数据库文件名初始化失败!");
    }
    else
    {
        Log.INFO("数据库文件名初始化成功!");
    }
    ret = myDataOpen(mydbfilename);
    if(ret < 0)
    {
        Log.INFO("数据库打开失败!");
    }
    else if (ret != 0)
    {    
        myDataCreateTable();
    }
    Log.INFO("数据库打开成功!");
}
Database::~Database()
{
    if(!myDataClose())
    {
        Log.INFO("数据库关闭失败!");
    }
    else
    {
        Log.INFO("数据库关闭成功!");
    }
}
#endif


使用方式:

Database data;
  data.insert("add", "66 83 0f", result);
  data.insert("addc", "83 0f", result);
  data.selectIns("add", "66 83 0f", p);
  printf("temp  %f - %f - %f - %f \n", temp[0], temp[1], temp[2], temp[3]);


执行结果:


13b6e1e3fcdc40078788ac709498f29b.png

相关文章
|
2天前
|
API 数据库 C语言
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
【C/C++ 数据库 sqlite3】SQLite C语言API返回值深入解析
175 0
|
2天前
|
存储 监控 安全
内网屏幕监控软件的数据存储与管理:使用SQLite数据库保存监控记录和配置信息
在当今数字化时代,安全和监控在企业和组织中变得至关重要。内网屏幕监控软件作为一种关键工具,帮助组织监视员工的活动并确保信息安全。这种软件不仅需要高效地记录和管理监控数据,还需要能够方便地进行配置和调整。本文将讨论如何使用SQLite数据库来保存监控记录和配置信息,并介绍如何通过自动化机制将监控到的数据提交到指定网站。
188 2
|
2天前
|
数据库 数据库管理 关系型数据库
|
2天前
|
数据库管理
Mac检出svn checkout报错 svn: E200030: SQLite 编译为 3.39.5,但是运行于 3.39.4
Mac检出svn checkout报错 svn: E200030: SQLite 编译为 3.39.5,但是运行于 3.39.4
12 0
|
2天前
|
SQL 存储 Ubuntu
在ubuntu中将dict.txt导入到数据库sqlite3
这样,你就成功将 `dict.txt` 中的数据导入到名为 `mydatabase.db` 的SQLite3数据库中的 `words` 表格中了。请根据实际情况调整表格结构和数据导入命令。
19 0
|
2天前
|
SQL 数据库 数据库管理
Python数据库操作(SQLAlchemy、SQLite等)面试题集
【4月更文挑战第15天】本文介绍了Python数据库操作的面试重点,涵盖SQLAlchemy ORM和SQLite。内容包括:1) 使用SQLAlchemy定义SQLite表的Python类及执行CRUD操作,强调ORM使用和会话管理;2) 查询优化与性能,涉及JOIN、分组、聚合查询,并提醒注意懒加载和索引创建;3) 异常处理和事务管理,展示如何捕获异常并进行事务控制。通过理解这些知识点并避免常见错误,可在面试中表现出色。
28 0
|
2天前
|
SQL 关系型数据库 数据库
Python中SQLite数据库操作详解:利用sqlite3模块
【4月更文挑战第13天】在Python编程中,SQLite数据库是一个轻量级的关系型数据库管理系统,它包含在一个单一的文件内,不需要一个单独的服务器进程或操作系统级别的配置。由于其简单易用和高效性,SQLite经常作为应用程序的本地数据库解决方案。Python的内置sqlite3模块提供了与SQLite数据库交互的接口,使得在Python中操作SQLite数据库变得非常容易。
|
2天前
|
关系型数据库 MySQL 数据库连接
Python+SQLite数据库实现服务端高并发写入
Python中使用SQLite内存模式实现高并发写入:创建内存数据库连接,建立表格,通过多线程并发写入数据。虽然能避免数据竞争,但由于SQLite内存模式采用锁机制,可能在高并发时引发性能瓶颈。若需更高性能,可选择MySQL或PostgreSQL。
43 0
|
2天前
|
数据库连接 API 数据库
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
SQLite3 数据库 C语言API 打开函数sqlite3_open 详解
68 0
|
2天前
|
关系型数据库 数据库 C++
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)