SQLite数据库使用(sqlite3 c++)_c++ sqlite3-程序员宅基地

技术标签: c++  sqlite3  

本文只针对sqlite3 c++ API调用。

1、基础知识

sqlite3只是一个嵌入式数据库引擎,占用资源非常底,可以适用于Windows和Linux,而且sqlite3只是一个文件,不需要服务器进程。

sqlite3 c++ api接口只需要引用sqlite3.h头文件就行。

常用术语表(table)、字段(column,列,属性)、记录(row,record)。

存储类型:integer(整型)、real(浮点型)、text(文本字符串)、blob(二进制数据)。

关键字:select、insert、update、delete、from、creat、where、desc、order、by、group、table、alter、view、index等,数据库中不能使用关键字命名表和字段。

2、数据库语句

2.1、创建或打开数据库

对应c++代码

    //不存在即创建数据库
    sqlite3* db;
    int res = sqlite3_open(sql_name,&db);
    if(res)
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        qDebug() << "database failed to open ";
    }
    else{
        qDebug() << "database open sucess";
    }

2.2、数据定义语句

  • 新建表 ⟹ create:create table 表名 (字段名1 字段类型1,字段名2 字段类型2,。。。); create table if not exists 表名 (字段名1 字段类型1,字段名2 字段类型2,。。。);

   CREATE TABLE IF NOT EXISTS t_person (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL); 

  • 删除表 ⟹ drop:dorp table 表名;drop table if exists 表名;

   DROP TABLE IF EXISTS t_person; 

对应c++代码:

//回调函数
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}
    //判断表是否存在
    /* Create SQL statement */
    char *sql = "CREATE TABLE IF NOT EXISTS COMPANY("  \  //只是创建表 "CREATE TABLE COMPANY("
          "ID INT PRIMARY KEY     NOT NULL," \
          "TIME_START           TEXT    NOT NULL," \
          "TIME_END             TEXT    NOT NULL," \
          "DETECT_IP            TEXT    NOT NULL," \
          "CONTAINER_NUM        TEXT    NOT NULL," \
          "REAL_RESULTS         TEXT    NOT NULL," \
          "DETECT_RESULTS       TEXT    NOT NULL," \
          "DETECT_TIME          TEXT    NOT NULL," \
          "NOTE                 TEXT    NOT NULL);";

    /* Execute SQL statement */
     char *zErrMsg = 0;
    int 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, "Table created successfully\n");
    }
    //若存在则删除表
    /* drop SQL statement */
    char *sql_d = "DROP TABLE IF EXISTS COMPANY;";   //删除表不做判断 "DROP TABLE COMPANY("


    /* Execute SQL statement */
     char *zErrMsg = 0;
    int rc = sqlite3_exec(db, sql_d, NULL, 0, &zErrMsg);
    if( rc != SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
       sqlite3_free(zErrMsg);
    }else{
       fprintf(stdout, "Table drop successfully\n");
    }

2.3、数据操作语句

  • 添加表中的数据 ⟹ insert:insert into 表名 (字段1,字段2,。。。) values (字段1的值,字段2的值);字符串内容用单引号。

   INSERT INTO t_person (name, age) VALUES ('大明', 22); 

  • 修改表中的数据 ⟹ update:update 表名 set 字段1 = 字段1的值,字段2 = 字段2的值,。。。;

    UPDATE t_person SET name = '小明', age = 10; // 把表中name字段的值全部改成小明,age字段的值全部改成10。  

    UPDATE t_person SET age = 12 WHERE name = '小明'; // 把表中name字段值是小明的age值改为12。  

  • 删除表中的数据 ⟹ delete:delete from 表名;delete from 表名 where 字段 = 字段值。

   DELETE FROM t_person; // 删除表中的所有记录。 

   DELETE FROM t_person WHERE age = 25; // 删除表中字段age等于25的这条记录。 

   DELETE FROM t_person WHERE age > 12 AND age < 15; // 删除表中年龄大于12且小于15的记录。 

写入数据方式一:


    sqlite3* db;
    int res = sqlite3_open(sql_name,&db);
    if(res)
    {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        qDebug() << "database failed to open ";
    }
    else{
        qDebug() << "database2 open sucess";
    }

    /* INSERT SQL statement */

    ID += 1;
    time_start =QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz").toLongLong();
    time.start();
    char *zErrMsg = 0;
    std::string local_ip = "'192.168.53.21'";
    int64_t  time_end =QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz").toLongLong();
    std::string container_num = "'#^XH^123456^42G1^'";
    QString  isEmptoy = "'空箱'";
    //char detect_results = 0x00;
    std::string detect_results_sql;
    std::string note = "''" ;
    qDebug()<< "detect_results   :  "<<detect_results;
   
        detect_results_sql = "'未执行检测'";
        note = "'设备防夹保护触发,设备停止运动'";

    int timeElapsed = time.elapsed();
    qDebug()<< "timeElapsed   :  "<<timeElapsed<<" ms";
    //float detect_time = float(time_end -time_start)/1000;
    float detect_time = float(timeElapsed)/1000;

    std::string sql_add = "INSERT INTO COMPANY (ID,TIME_START,TIME_END,DETECT_IP,CONTAINER_NUM,REAL_RESULTS,DETECT_RESULTS,DETECT_TIME,NOTE) "
                          "VALUES(" + std::to_string(ID)+","+ std::to_string(time_start)+","+ std::to_string(time_end)+","+local_ip+","
                         ""+container_num+","+isEmptoy.toStdString()+","+detect_results_sql+","+std::to_string(detect_time)+","+note+"); " ;

    /* Execute SQL statement */
    int rc = sqlite3_exec(db, sql_add.c_str(), callback, 0, &zErrMsg);
    if( rc != SQLITE_OK ){
       fprintf(stderr, "SQL error: %s\n", zErrMsg);
       sqlite3_free(zErrMsg);
    }else{
       fprintf(stdout, "INSERT2 created successfully\n");
    }
        sqlite3_close(db);
}

写入数据方式二:

第二种写入数据的方式------------------------------------------
    sqlite3_exec(db,"begin;",0,0,0);
    int64_t  time_start =QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz").toLongLong();
    std::string local_ip = "192.168.53.21";
    sqlite3_stmt *stmt;
    const char* sql_insert = "INSERT INTO COMPANY (ID,TIME_START,DETECT_IP) VALUES(?,?,? );" ;
    int ret = sqlite3_prepare_v2(db,sql_insert,-1,&stmt,0);
    if(ret == SQLITE_OK)
    {
        sqlite3_bind_int(stmt,1,1);
        sqlite3_bind_int64(stmt,2,time_start);
        //sqlite3_bind_text(stmt,2,local_ip.c_str(),-1,SQLITE_STATIC);
        sqlite3_bind_text(stmt,3,local_ip.c_str(),-1,SQLITE_STATIC);
        ret = sqlite3_step(stmt);
//        if(rc != SQLITE_DONE)
//        {
//            fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
//            sqlite3_close(db);
//        }
        sqlite3_reset(stmt);
        sqlite3_finalize(stmt);
    }
    else
    {
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
    }
    sqlite3_exec(db,"commit;",0,0,0);
    sqlite3_free(zErrMsg);

2.3查询数据

  • select:select 字段1, 字段2, 。。。 from 表名;select 字段1, 字段2, 。。。 from 表名 where 字段 = 某值;select * from 表名;(查询所有的字段)
  • 表别名:select 字段1 别名, 字段2 别名,。。。from 表名 别名;select 字段1 别名, 字段2 as 别名,。。。from 表名 as 别名;select 别名.字段1,别名.字段2,。。。from 表名 别名;

   SELECT name, age FROM t_person WHERE age < 80; 

   SELECT * FROM t_person WHERE age < 80; 

   SELECT name, age nianling FROM t_person ren WHERE ren.age > 80 AND nianling < 90; 

  • 计算记录条数:select count(字段或者*) from 表名;

   SELECT count(name) FROM t_person ren WHERE ren.age > 80; 

   SELECT count(*) FROM t_person ren WHERE ren.age > 80; 

  • where:where 字段 = 某值;where 字段 is 某值;where 字段 != 某值;where 字段 is not 某值;where 字段 > 某值;where 字段1 = 某值1 and 字段2 < 某值2;where 字段1 = 某值1 or 字段2 > 某值2;
  • order by:select * from 表名 order by 字段(默认升序);select * from 表名 order by 字段 desc(降序);select * from 表名 order by 字段 asc(升序);select * from 表名 order by 字段1 asc(先按字段1升序),字段2 desc(再按字段2降序);

   SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC; // 先按年龄降序,再按名字升序。  

  • limit:select * from 表名 limit 数值1,数值2;分页查询,数值1表示跳过前面多少条,数值2表示取出之后多少条。select * from 表名 limit 数值2;(跳过前面0条,相当于select * from 表名 limit 0,数值2,表示最前面多少条数据)

   SELECT * FROM t_person WHERE age < 100 ORDER BY age DESC, name ASC LIMIT 3, 5; // 先筛选,后排序,再分页。 

  • like:模糊查询,select 字段1, 字段2, 。。。 from 表名 where 字段 like %某值%;

   SELECT * FROM t_person WHERE name like '%明%'; 

查询ID:(用处:获取当前数据库的所写的行数)

    //获取当前数据库最大ID值
    char **dbresult;
    int nrow,ncolumn;
    char *sql_select = "SELECT * from COMPANY";
    res = sqlite3_get_table(db,sql_select,&dbresult,&nrow,&ncolumn,&zErrMsg);
    if(res == SQLITE_OK)
    {
        //查询成功
        ID = nrow;
        qDebug() << "nrow :" <<  nrow;
    }
    else{
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        qDebug() << "SELECT error :" ;
    }
    //释放 dbresult 的查询结果
    sqlite3_free_table(dbresult);

3、Ubuntu和nano安装sqlite3

3.1、Ubuntu安装sqlite3

sudo apt-get install sqlite3
//查看版本信息
sqlite3 -version

3.2、nano安装sqlite3

使用apt在Nano上安装,但是找不到sqlite3.h,所以只能使用源码编译。

下载源码:SQLite Download Page

//解压
tar xvzf sqlite-autoconf-3310100.tar.gz
//进入sqlite文件夹
cd sqlite-autoconf-3310100
//配置文件
./configure
//开始编译
make
//写入系统文件中
sudo make install
//查看文件路径
dpkg -L sqlite3

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/PC1022/article/details/123812056

智能推荐

FPGA 基于双端口RAM的串口通信系统_fpga双口sram通信-程序员宅基地

文章浏览阅读1.4k次。FPGA实验报告文章目录一、概述1、目的及意义:2、主要功能:二、原理及步骤1、原理框图:2、工作原理3、功能模块简介4、实验步骤三、程序设计及描述四、仿真与综合测试五、总结一、概述1、目的及意义:设计居于双端口RAM的串口的通信系统。实现用COMPORT发送数据,并在FPGA上用七段数码管显示出来。2、主要功能:FIFO队列是一种数据缓冲器,用于数据的缓存。他是一种先入先出的存储器,即最先写入的数据,最先读。FIFO的参数有数据深度和数据宽度。数据宽度是指存储数据的宽度。深度是指存储器可_fpga双口sram通信

神经网络(vanilla ver.) in numpy_vanillaw神经网络 python-程序员宅基地

文章浏览阅读2k次。写在最前vanilla neural network 学习材料有好多 前年年都是用MATLAB写的,写的还挺丑,后来用tensorflow写把底层细节都盖住了。 这里是一个只用numpy实现的版本学习材料的话。MATLAB推荐王小川的 45个神经网络案例 第一章 数学推导推荐吴恩达的Ufldl 反向传导算法细节activation function 的求导比较有技巧sigmoid : 1_vanillaw神经网络 python

人脸对齐--Face Alignment In-the-Wild: A Survey_人脸对齐 综述-程序员宅基地

文章浏览阅读8.2k次。Face Alignment In-the-Wild: A Survey Computer Vision and Image Understanding Volume 162, September 2017, Pages 1-22 https://www.sciencedirect.com/science/article/pii/S1077314217301455人脸对齐综述文献人脸对齐的定_人脸对齐 综述

模板——并差集_力扣和acm-程序员宅基地

文章浏览阅读106次。并差集_ACM模板题目描述第1行给出两个正整数,分别是城镇数目N (N < 1000 )和道路数目M。随后的M行对应M条道路,每行给出一对正整数,分别是该条道路直接连通的两个城镇的编号。为简单起见,城镇从1到N编号。要使任何两个城镇间都可以实现交通,但不一定有直接的道路相连,只要互相间接通过道路可达即可,输出最少还需要建设的道路数目?const int maxn = 1010;//N..._力扣和acm

分层强化学习 学习笔记-程序员宅基地

文章浏览阅读1.5k次,点赞5次,收藏25次。MLSH的idea很自然,简单有效,temporal abstraction的做法和common 的 HRL方法基本一致需要注意的一点是,通常single task中,为了training的稳定性,会keep master policy random,warmup subpolicy,这是希望master policy能在subpolicy有一定level之后,再进行有效learning;_分层强化学习

山东中职计算机应用基础课件,计算机应用基础课件(中职)-精选版.ppt-程序员宅基地

文章浏览阅读318次。计算机应用基础课件(中职)-精选版.ppt计算机应用基础 目录 第一章 计算机基础知识 1.1 计算机的定义 计算机又称“电脑”。 电子计算机是一种可以输入、输出、处理、存储数据和 信息,无需人类干预的一类电子设备。 1.2 计算机的发展历程 ? 1946年2月14日,世界上第一台电脑ENIAC在美国 ...

随便推点

Docker的ARG、ENV和.env配置完整指南_docker env-程序员宅基地

文章浏览阅读1.7w次,点赞5次,收藏14次。本文将帮助您自信地使用 Docker ARG、ENV、env_file 和 .env 文件。您将了解如何使用 Docker 构建时变量、环境变量和 docker-compose 模板轻松配置 Docker 映像和 dockerized 应用程序。常见的误解.env 文件仅在使用docker-compose.yml 文件时的预处理步骤中使用。美元符号变量(如 $HI)被替换为同一目录中名为“.env”的文件中包含的值。ARG仅在构建 Docker 映像(RUN ..._docker env

数的三次方根 JAVA解法_java如何表示三次根-程序员宅基地

文章浏览阅读3.4k次。给定一个浮点数n,求它的三次方根。输入格式共一行,包含一个浮点数n。输出格式共一行,包含一个浮点数,表示问题的解。注意,结果保留6位小数。数据范围−10000≤n≤10000−10000≤n≤10000输入样例:1000.00输出样例:10.000000import java.util.*;public class Main{ pu..._java如何表示三次根

汇编语言——学习资料(更新........)-程序员宅基地

文章浏览阅读1.4k次,点赞3次,收藏12次。知乎引用“ 学汇编不是说一定要用这玩艺做多牛鼻的事情, 问题的关键在于, 学透了汇编会使你真正理解计算机另外一方面, 如上面所说, 在工作中你迟早会在某个阴暗的角落遇到汇编. 不管你承认不承认, 现在的CPU没有直接跑高级语言的, 哪怕是虚拟机也都是类似汇编的指令集.当遇到崩溃分析, 性能优化甚至编译器抽风等等的时候, 汇编是你最后一根救命稻草.”作者:Skogkatt 链接:https://w

经典算法之递归(Recursion)_recursion算法编程-程序员宅基地

文章浏览阅读6.5k次,点赞5次,收藏28次。1、递归的定义  递归:你打开面前这扇门,看到屋里面还有一扇门(这门可能跟前面打开的门一样大小(静),也可能门小了些(动)),你走过去,发现手中的钥匙还可以打开它,你推开门,发现里面还有一扇门,你继续打开,。。。, 若干次之后,你打开面前一扇门,发现只有一间屋子,没有门了。 你开始原路返回,每走回一间屋子,你数一次,走到入口的时候,你可以回答出你到底用这钥匙开了几扇门。  循环:你打开面前..._recursion算法编程

Visio2016通过部署工具的方式进行安装_已有visio安装包怎么用部署工具安装-程序员宅基地

文章浏览阅读1.5k次。由于我电脑是Office2016的版本,我下载好visio2016后,解压到文件夹。由于之前安装的是即点即用的office,所以出现了以下问题:后来在网上查到可以使用部署工具进行安装,点击一下网站进行下载office部署工具:https://www.microsoft.com/en-us/download/details.aspx?id=491171.首先下载好部署工具,解压该工具到visio中setup.exe文件夹中2.运行该工具,选择visio中setup.exe文件夹生成相应的c_已有visio安装包怎么用部署工具安装

【沙发管家】电视猫3.1.6新版体验:资源更全面,院线大片看到爽!-程序员宅基地

文章浏览阅读160次。近日电视猫迎来了最新版本(V3.1.6)的更新,此次更新除了新增的奇趣频道,优化了智能推荐算法,最大的亮点,应该就是新推出的影视VIP服务了,新版极大地扩展了内容包(电影、电视剧、综艺、少儿、海外剧、纪录片),资源更全面。下面我们就一起体验一番最新版电视猫的不同之处吧。近日电视猫迎来了最新版本(V3.1.6)的更新,此次更新除了新增的奇趣频道,优化了智能推荐算法,最大的亮点,应该就是新推出的影..._电视猫3.1.6

推荐文章

热门文章

相关标签