• SQLite3 操作命令以及c/c++编程API和例子


    数据库系统

    DBMSdata base management system (数据库管理系统)。数据库管理系统通过数据模型对数据进行存储和管理。数据模型三要素:数据结构、数据操作、完整性约束。数据库管理系统采样的数据模型注意有三种:层次模型、网状模型、关系模型。

    1. 层次模型:

      • 有且仅有一个节点无父结点,这个节点被称为根节点
      • 其他节点有且仅有一个父节点
      • 同一父节点的子节点被称为兄弟节点
      • 没有子节点的节点被称为页节点
    2. 网状模型

      • 允许一个以上的节点无父节点
      • 一个节点可以有多个的父节点
    3. 关系模型

      • 每一列的分量是类型相同的数据

      • 列的顺序可以是任意的

      • 行的顺序可以是任意的

      • 表中的分量是不可再分割的最小数据项,即表中不允许有子表。

      • idnameaddr
        1王五北京
        2张三上海
        3李四珠海

    常用的数据库:ORACLE、Mysql、SQL server、Access、Sybase、SQLite。

    SQLite

    SQite是一个开源的、内嵌式的关系型数据库。下载地址:https://www.sqlite.org/download.html 。学习网站菜鸟教程: https://www.runoob.com/sqlite/sqlite-tutorial.html

    特点:零配置、灵活、可移植、自由授权、紧凑、可靠、简单、易用。

    SQLite数据类型

    • interger:带符号的整型(最大64位)
    • real:8字节表示的浮点类型
    • text:字符类型,支持多种编码(UTF-8、UTF-16等),大小无限制
    • blob:任意数据类型,大小无限制。BLOB(binary large object)二进制大对象,使用二进制保持数据
    • null:null值,表示空

    SQLite语句介绍

    • 创建打开数据库:splite3 xxx.dbsqlite3>.open test.db
    • 退出数据库:sqlite3>.quit/sqlite3>.exit
    • 查看数据库列表:splite3>.databases
    • 导出完整的数据库在一个文本文件中: sqlite3 testDB.db .dump > testDB.sql,恢复使用:sqlite3 testDB.db < testDB.sql
    • 所有的SQL语句都是使用分号结尾,不区分大小写,两个减号“--”代表注释。

    表的创建和查看

    create table 数据库.表名称(列名称1 数据类型,列名称2 数据类型,列名称3 数据类型,....);
    .tables -- 查看创建的表名称
    -- sqlite> .tables
    -- tbl
    .schema -- 查看表格的语句
    -- sqlite> .schema
    -- CREATE TABLE tbl(id interger,name text,addr text);
    select * from tbl;  -- 查询表中的内容
    -- 在设计表时,通过primary key手动设置主键,每个表只能由一个主键,设置主键的列的数据不能重复。
    create table persons(id integer primary key,name text,addr text);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    表的删除插入和修改

    drop table table_name; -- 删除表
    -- alter语句,在已有的表中添加或者删除列以及修改表名
    alter table 表名 add 列名 数据类型; -- 添加列
    alter table persons add column sex text;
    alter table 表名 rename to 新表名 -- 修改表名
    -- 插入新行 insert into
    insert into 表名 values(列值1,列值2,列值3,.....); -- 当列值位字符串要加上‘’号
    insert into table_name (column1, column2, ...) values (value1, value2, ...); -- 插入指定列
    insert into tbl(102,'ds','ss');
    insert into tbl(id,name,addr) values(103,'io','op');
    -- 更新update
    update tbl set addr='ji' where id=103;
    select * from tbl where id<102;
    select * from tbl where id between 102 and 105;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    表数据的删除

    delete from 表名 [匹配条件];
    delete from table_name where id=104;
    delete from table_name where id=104 and addr='cq';
    select * from table_name where id in (102,103,104);
    select * from table_name where addr like 'ps%'; -- ps开头的
    -- like通配符百分号(%)代表零个、一个或多个数字或字符。下划线(_)代表一个单一的数字或字符
    select * from table_name where addr GLOB 'ps%'; -- ps开头的
    -- GLOB星号(*)代表零个、一个或多个数字或字符。问号(?)代表一个单一的数字或字符
    select * from table_name where id=104 or addr='cq';
    select * from tbl where id between 104 and 109;
    select * from tbl where id is not 109; -- 当id!=109时
    select * from tbl where id is 109; -- 当id=109时
    select * from COMPANY limit 3 offset 2; -- limit限制显示的行数,offset偏移量为多少
    select * from COMPANY order by NAME, SALARY desc; -- 安装NAME升序 SALARY降序排列 默认升序
    -- asc 默认值,从小到大,升序排列  desc 从大到小,降序排列
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    复制表和修改表结构

    create table tbl2 as select * from tbl; -- 复制一张表
    create table tbl3 as select * from tbl where id=103; -- 复制部分
    -- 修改表的结构
    create table tbl4(id integer primary key,name text,addr text); -- 第一步创建新表
    insert into tbl4(id,name,addr) select id,name,addr from tbl; -- 第二步导入数据
    drop table tbl;
    alter table tbl4 rename to tbl; -- 更该表名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    事务处理

    begin; -- 开始一个事务
    commit; -- 使得begin后的所有命令得到确认
    rollback; -- 取消begin后的所有操作
    sqlite> BEGIN;
    sqlite> DELETE FROM COMPANY WHERE AGE = 25;
    sqlite> COMMIT;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    函数操作

    length() -- 返回字符串的长度
    lower() -- 将字符串转换为小写
    upper() -- 将字符串转换为大写
    select id,upper(name),length(addr) from tbl;
    avg() -- 返回某列的平均值
    count() -- 返回某列的函数
    max() -- 返回某列的最大值
    min() -- 返回某列的最小值
    sum() -- 求某列的总和
    select id,name,addr,max(scores),avg(scores) from tbl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    数据分组group by

    select class,count(*) from tbl group by class; -- group分组
    -- where语句必须要在group之前
    select class,avg(scores) from tbl where class='class_a' group by class;
    -- having语句对结果进行过滤,在group后面
    select class,avg(scores) from tbl group by class having avg(scores)>=60;
    -- order by 对结果进行排序 放在having后面
    select class,avg(scores) from tbl group by class 
    	having avg(scores)>=60 order by avg(scores) desc; -- 使用平均成绩降序排序
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    约束

    • NOT NULL 约束:确保某列不能有 NULL 值。
    • DEFAULT 约束:当某列没有指定值时,为该列提供默认值。
    • UNIQUE 约束:确保某列中的所有值是不同的。是唯一的。
    • PRIMARY Key 约束:唯一标识数据库表中的各行/记录。
    • CHECK 约束:CHECK 约束确保某列中的所有值满足一定条件。使得输入的数据是合法的。
    create table tbln(
    	id integer primary key not null autoincrement, -- 主键 非空 自增长
        name text not null unique, -- 唯一
        age integer not null, -- 非空
        address text,
        salary real default 5000.0 check(salary>0) -- 默认5000.0 检查大于0
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    联结表

    联结表就是从多个表中查询数据

    select 列名1,列名2,.... from 表1,表2,.... where 判断语句;
    select perosns.name, persons.addr, grade.score, grade.years from persons, grade where
    	persons.id = grade.id and perosns.name = 'lucy';
    
    • 1
    • 2
    • 3

    视图view

    通过相关的名称存储在数据库中的一个 SQLite 语句。

    -- 创建视图
    create view result as select perosns.name, persons.addr, grade.score, grade.years 
    from persons, grade where persons.id = grade.id and perosns.name = 'lucy';
    -- 删除视图
    drop view result;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    触发器trigger

    SQLite的触发器是数据库的回调函数,他会在指定的数据库事件发生的时候自动的执行调用。SQLite 的触发器(Trigger)可以指定在特定的数据库表发生 delete、insert或 update 时触发,或在一个或多个指定表的列发生更新时触发。

    create trigger trigger_name  [before | after] 
    [insert | update| delete] on table_name
    begin
     -- 触发器逻辑....
    end;
    
    create trigger trigger_name  [before | after] 
    update on table_name of column_name -- 发生某个列上面
    begin
     -- 触发器逻辑....
    end;
    -- 创建触发器
    create trigger tg_delete after delete on persons 
    begin 
    	delete from grade where id=old.id; -- 回调函数
    end;
    -- 查看触发器
    select name from sqlite_master where type = 'trigger';
    select name from sqlite_master where type = 'trigger' and tbl_name = 'COMPANY';
    -- 删除触发器
    drop trigger trigger_name;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    日志操作

    create table log(time text, date text, data text); -- 创建日志表
    insert into log values(time('now'),date('now'), '日志信息'); -- 添加信息
    -- 创建触发器
    create trigger log_trigger after update on persons
    begin
    	insert into log values(time('now'),date('now'), '执行了update');
    end;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    索引 index

    -- 索引创建建议
    -- 在作为主键的列上 在经常需要排列的列上创建索引
    -- 在经常使用where子句中的列上面创建索引,加快条件的判断速度
    create index index_name on table_name;
    create index index_name on table_name(column_name); -- 单列索引
    .indices 或者 .indexes -- 查看索引
    select * from sqlite_master where type = 'index'; -- 列出数据库的所有索引
    drop index 索引名; -- 删除索引
    create unique index index_name on table_name (column_name); -- 唯一索引
    create index index_name on table_name (column1, column2); -- 组合索引
    -- 索引避免使用情况 索引是为了在大数据库中实现收索、查找、条件查找
    -- 表的数据量不大,表的大部分操作不是查询,大量出现NULL的不建议使用索引。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    SQLite c/c++编程

    注意点:sqlite使用了两个动态库 pthread 和 dl。在网站: https://www.sqlite.org/cintro.html 中查看库中的各个函数的具体情况。学习网址:https://www.jb51.net/list/list_215_1.htm

    在这里插入图片描述

    sqlite3_open

    int sqlite3_open(  // 打开数据库
      const char *filename,   /* Database filename (UTF-8) */
      sqlite3 **ppDb          /* OUT: SQLite db handle */
    );
    filename: 数据库文件路径
    ppDb: 指向sqlite3的句柄指针
    返回值: 0 SQLITE_OK 成功 其他错误码(非零值)失败
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    sqlite3_close

    int sqlite3_close(sqlite3* pdb); // 关闭数据库文件
    pdb: 关闭的sqlite数据库
    返回值: 0 SQLITE_OK 成功 其他错误码失败
    
    • 1
    • 2
    • 3

    sqlite3_exec

    int sqlite3_exec( // 执行SQL操作
      sqlite3* pdb,                                  /* An open database */
      const char *sql,                           /* SQL to be evaluated */
      int (*callback)(void*,int,char**,char**),  /* Callback function */
      void *arg,                                    /* 1st argument to callback */
      char **errmsg                              /* Error msg written here */
    );
    pdb: 数据库句柄
    sql: SQL语句
    callback: 回调函数,在使用select语句的时候使用,其他忽略
    arg: 传递给回调函数的第一个参数
    errmsg: 错误信息指针的地址
    返回值: 0 SQLITE_OK 成功 其他错误码
    // 回调函数 每找到一条记录,自动执行一次回调函数
    typedef int (*sqlite3_callback)(void* arg, int f_num, char** f_value, char** f_name); 
    arg: 传递给回调函数的参数
    f_num: 记录中包含的字段数目
    f_value: 包含每个字段值的指针数组
    f_name: 包含每个字段名称的指针数组
    返回值:0 成功 -1 失败
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    sqlite3_get_table

    // 执行zsql指向的sql语句,将结果集相关数据的地址保存在函数的参数中
    int sqlite3_get_table( 
      sqlite3 *db,          /* An open database */
      const char *zSql,     /* SQL to be evaluated */
      char ***pazResult,    /* Results of the query */
      int *pnRow,           /* Number of result rows written here */
      int *pnColumn,        /* Number of result columns written here */
      char **pzErrmsg       /* Error msg written here */
    );
    db: 数据库的标识
    zsql: SQL语句,以分号结尾
    pazResult: 指针数组的地址,记录结果集数据。
        内存布局:先依次存放各列的列名,然后是每一行各列的值。
    pnRow:行数的指针地址
    pnColumn: 列数的指针地址
    pzErrmsg: 错误信息指针的地址
    
    void sqlite3_free_table(char **result);
    // 释放动态分配的收集结果的sqlite3_get_table参数pazResult
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    实现数据库操作example1.c

    使用上面的函数,实现学生成绩的数据库函数

    #include "sqlite3.h"
    #include 
    #include 
    #include 
    #include 
    
    /**
     * @details 实现数据库的打开和创建表的功能
     * @param sqlite3_filename 打开的数据库的路径名称
     * @return 返回打开数据库的句柄指针 NULL 失败 非空 成功
    */
    sqlite3* sql_open(const char* sqlite3_filename)
    {
        sqlite3 *sqlite3_db = NULL;
        int sqlite3_ret = sqlite3_open(sqlite3_filename, &sqlite3_db);
        if(sqlite3_ret != SQLITE_OK)
        {
            perror("sqlite3_open error");
            return NULL;
        }
        printf("sqlite3_open ok!\r\n");
        return sqlite3_db;
    }
    
    /**
     * @details 创建一个表
     * @param sqlite3_db 打开的数据库句柄
     * @param tbname 创建的表的名字
     * @return -1失败 0成功
    */
    int create_table(sqlite3 *sqlite3_db, const char* tbname)
    {
        char *sql = (char*)sqlite3_malloc(100);
        if(sql == NULL)
            return -1;
        memset(sql, '\0', 100); /*初始化申请的内存都为'\0'*/
        sprintf(sql, "create table %s (id int primary key not null,name text,score float);", tbname);
    
        char *mesg_error = NULL;
        int ret = sqlite3_exec(sqlite3_db, sql, NULL, NULL, &mesg_error);
        if(ret != SQLITE_OK)
        {
            if(strcmp(mesg_error, "table stu already exists") != 0)
            {
                printf("%s\n", mesg_error);
                sqlite3_free(mesg_error);
                sqlite3_free(sql);
                return -1;
            }
        }
        printf("create ok\n");
        if(sql != NULL)
            sqlite3_free(sql);
        sqlite3_free(mesg_error);
    
        return 0;
    }
    
    /**
     * @details 给数据库中插入数据
     * @param sqlite3_db 数据库句柄
     * @param tbname 表名
     * @return 0 成功 -1 失败
    */
    int insert_data(sqlite3 *sqlite3_db, const char* tbname)
    {
        char *sql = (char*)sqlite3_malloc(100);
        int id;
        char name[10] = {'\0'};
        float score;
        if(sql == NULL)
            return -1;
        memset(sql, '\0', 100); /*初始化申请的内存都为'\0'*/
        printf("请分别输入你的id name score\n");
        scanf("%d%s%f",&id, name, &score);
        sprintf(sql, "insert into %s values(%d,'%s',%.1f);", tbname, id, name, score);
        printf("%s\n",sql);
    
        char *mesg_error = NULL;
        int ret = sqlite3_exec(sqlite3_db, sql, NULL, NULL, &mesg_error);
        if(ret != SQLITE_OK)
        {
            printf("%s\n", mesg_error);
            sqlite3_free(mesg_error);
            sqlite3_free(sql);
            return -1;
        }
        printf("insert ok\n");
        if(sql != NULL)
            sqlite3_free(sql);
        sqlite3_free(mesg_error);
    
        return 0;
    }
    
    /**
     * @details select查询的回调函数,每查询到一个执行一次回调函数
     * @param data 传递给回调函数的参数
     * @param column_num 列数
     * @param column_value 存放列值的数组
     * @param column_name 存放列名的数组
     * @return 0 成功 其他 失败
    */
    int callback(void* data, int column_num, char* column_value[], char* column_name[])
    {
    
        printf("%d, %s, %.1f\n", atoi(column_value[0]), column_value[1], atof(column_value[2]));    
        return 0;
    }
    
    /**
     * @details 查询显示表的数据
     * @param sqlite3_db 数据库句柄
     * @param tbname 表的名称
     * @return 0 成功 -1 失败
    */
    int select_data(sqlite3 *sqlite3_db, const char* tbname)
    {
        char *sql = (char*)sqlite3_malloc(100);
        if(sql == NULL)
            return -1;
        memset(sql, '\0', 100); /*初始化申请的内存都为'\0'*/
    
        sprintf(sql, "select * from %s;", tbname);
        printf("%s\n",sql);
    
        char *mesg_error = NULL;
        int ret = sqlite3_exec(sqlite3_db, sql, callback, NULL, &mesg_error);
        if(ret != SQLITE_OK)
        {
            printf("%s\n", mesg_error);
            sqlite3_free(mesg_error);
            sqlite3_free(sql);
            return -1;
        }
        printf("select ok\n");
        if(sql != NULL)
            sqlite3_free(sql);
        sqlite3_free(mesg_error);
    
        return 0;
    }
    
    /**
     * @details 查询显示表的数据
     * @param sqlite3_db 数据库句柄
     * @param tbname 表的名称
     * @return 0 成功 -1 失败
    */
    int select_data_by_get_table(sqlite3 *sqlite3_db, const char* tbname)
    {
        char *sql = (char*)sqlite3_malloc(100);
        if(sql == NULL)
            return -1;
        memset(sql, '\0', 100); /*初始化申请的内存都为'\0'*/
    
        sprintf(sql, "select * from %s;", tbname);
        printf("%s\n",sql);
    
        char *mesg_error = NULL;
        char **dbResult;
        int nRow, nColumn, i, j, index;
    
        int ret = sqlite3_get_table(sqlite3_db, sql, &dbResult, &nRow, &nColumn, &mesg_error);
        if(ret != SQLITE_OK)
        {
            printf("%s\n", mesg_error);
            sqlite3_free_table( dbResult );
            sqlite3_free(mesg_error);
            sqlite3_free(sql);
            return -1;
        }
        printf("select ok\n");
        printf("nRow = %d, nColumn = %d \n", nRow, nColumn);
        index = nColumn;
    
        for(i = 0; i < nRow; i++)
        {
            printf("第%d条记录\n", i + 1);
            for(j = 0; j < nColumn; j++)
            {
                printf("字段名:%s 字段值:%s\n", dbResult[j], dbResult[index]);
                ++index;
            }
            printf("\n");
        }
    
        if(sql != NULL)
            sqlite3_free(sql);
        sqlite3_free(mesg_error);
    
        return 0;
    }
    
    /**
     * @details 更新表的数据,成绩
     * @param sqlite3_db 数据库句柄
     * @param tbname 表的名称
     * @param score 成绩
     * @param name 谁的成绩
     * @return 0 成功 -1 失败
    */
    int update_data(sqlite3 *sqlite3_db, const char* tbname, float score, char *name)
    {
        char *sql = (char*)sqlite3_malloc(100);
        if(sql == NULL)
            return -1;
        memset(sql, '\0', 100); /*初始化申请的内存都为'\0'*/
    
        sprintf(sql, "update %s set score = %.1f where name = '%s'", tbname, score, name);
        printf("%s\n",sql);
    
        char *mesg_error = NULL;
        int ret = sqlite3_exec(sqlite3_db, sql, NULL, NULL, &mesg_error);
        if(ret != SQLITE_OK)
        {
            printf("%s\n", mesg_error);
            sqlite3_free(mesg_error);
            sqlite3_free(sql);
            return -1;
        }
        printf("update ok\n");
        if(sql != NULL)
            sqlite3_free(sql);
        sqlite3_free(mesg_error);
    
        return 0;
    }
    
    /**
     * @details 删除数据
     * @param sqlite3_db 数据库句柄
     * @param tbname 表的名称
     * @param id 删除谁的数据
     * @return 0 成功 -1 失败
    */
    int delete_data(sqlite3 *sqlite3_db, const char* tbname, int id)
    {
        char *sql = (char*)sqlite3_malloc(100);
        if(sql == NULL)
            return -1;
        memset(sql, '\0', 100); /*初始化申请的内存都为'\0'*/
    
        sprintf(sql, "delete from %s where id = %d", tbname, id);
        printf("%s\n",sql);
    
        char *mesg_error = NULL;
        int ret = sqlite3_exec(sqlite3_db, sql, NULL, NULL, &mesg_error);
        if(ret != SQLITE_OK)
        {
            printf("%s\n", mesg_error);
            sqlite3_free(mesg_error);
            sqlite3_free(sql);
            return -1;
        }
        printf("delete ok\n");
        if(sql != NULL)
            sqlite3_free(sql);
        sqlite3_free(mesg_error);
    
        return 0;
    }
    
    void print_menu()
    {
        printf("\t\t\t 输入你的操作: \t\t\t\n");
        printf("\t\t\t 1.insert \t\t\t\n");
        printf("\t\t\t 2.delete \t\t\t\n");
        printf("\t\t\t 3.update \t\t\t\n");
        printf("\t\t\t 4.select_by_exec \t\t\t\n");
        printf("\t\t\t 5.select_by_table \t\t\t\n");
        printf("\t\t\t -1.exit \t\t\t\n");
    }
    
    int main(int argc, char* argv[])
    {
    
        sqlite3 *db;
        char tbname[20] = "stu";
        char name[10] = {'\0'};
        int id;
        float score;
    
        db = sql_open("test.db");
        create_table(db, tbname);
    
        int option;
    
        while(1)
        {
            print_menu();
            scanf("%d",&option);
            switch(option)
            {
                case -1:
                {
                    exit(-1);
                    break;
                }
                case 1:
                {
                    insert_data(db, tbname);
                    break;
                }
                case 2:
                {
                    printf("请输入你的id\n");
                    scanf("%d", &id);
                    delete_data(db, tbname, id);
                    break;
                }
                case 3:
                {
                    printf("请输入你的姓名以及成绩");
                    scanf("%s%f", name, &score);
                    update_data(db, tbname, score, name);
                    break;
                }
                case 4:
                {
                    select_data(db, tbname);
                    break;
                }
                case 5:
                {
                    select_data_by_get_table(db,tbname);
                    break;
                }
                default:
                    break;
            }
            sleep(1);
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336

    sqlite3_prepare_v2

    int sqlite3_prepare_v2(
      sqlite3 *db,              // 数据库连接对象
      const char *zSql,         // SQL 查询语句
      int nByte,                // SQL 查询语句的字节数 -1 自动计算
      sqlite3_stmt **ppStmt,    // 编译后的语句对象指针
      const char **pzTail       // 剩余未编译部分的指针 一般填0
    );
    // 将准备的sql语句解析到ppStmt结构体中去
    int sqlite3_finalize(sqlite3_stmt *pStmt);
    // 释放已经准备好的sqlite3_stmt sql解析好的结构体数据
    
    sqlite3_prepare_v2(db, “insert into tbl(ID,file_content) values( 10, ?), -1, &stat, 0);
    // 上面的?号表示不确定 需要使用sqlite3_bind_xxx类函数来确定,
    // 该类型的函数其中的第二个参数就是表示第几个?号
    // sqlite3_reset(pStmt) 重新初始化绑定的数据
    sqlite3_bind_double(pStmt, 1, 10.9); // 绑定数据10.9
    
    int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
    int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
                            void(*)(void*));
    int sqlite3_bind_double(sqlite3_stmt*, int, double);
    int sqlite3_bind_int(sqlite3_stmt*, int, int);
    int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
    int sqlite3_bind_null(sqlite3_stmt*, int);
    int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
    // 一般最后一个参数填写 SQLITE_TRANSIENT 自动管理释放内存
    int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
    int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
                             void(*)(void*), unsigned char encoding);
    int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
    int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
    int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
    int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    sqlite3_step

    int sqlite3_step(sqlite3_stmt* pStmt); // 执行结构体pStmt中解析的sql语句
    // 执行完一般需要执行 sqlite3_finalize 释放pStmt内存
    
    • 1
    • 2

    sqlite3_colmun_xxx

    // 获取sqlite3_stmt的当前结果行中的列的各种结果。
    const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); // 获取二进制数据
    double sqlite3_column_double(sqlite3_stmt*, int iCol);
    int sqlite3_column_int(sqlite3_stmt*, int iCol);
    sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
    const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
    const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
    sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
    int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
    int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
    int sqlite3_column_type(sqlite3_stmt*, int iCol);
    int sqlite3_column_count(sqlite3_stmt*) // 获取列的数量
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    实现数据库操作example2.c

    #include 
    #include 
    #include 
    #include "sqlite3.h"
    
    sqlite3* do_test_open(const char * datebase)
    {
        sqlite3* db = NULL;
        int result = sqlite3_open(datebase, &db);
        if(result != SQLITE_OK)
        {
            sqlite3_close(db);
            return NULL;
        }
        return db;
    }
    
    int do_test_create(sqlite3* db)
    {
        const char* create_table_sql = 
                    "create table testtable(int_col int,float_col real,string_col text);";
        sqlite3_stmt* stmt = NULL;
        // int len = strlen(create_table_sql);
    
        if(sqlite3_prepare_v2(db, create_table_sql, -1, &stmt, NULL) != SQLITE_OK)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
    
        if(sqlite3_step(stmt) != SQLITE_DONE)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
        if(stmt)
            sqlite3_finalize(stmt);
        printf("create\r\n");
        return 0;
    }
    
    int do_test_begin(sqlite3* db)
    {
        const char* create_table_sql = 
                    "begin;";
        sqlite3_stmt* stmt = NULL;
        // int len = strlen(create_table_sql);
    
        if(sqlite3_prepare_v2(db, create_table_sql, -1, &stmt, NULL) != SQLITE_OK)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
    
        if(sqlite3_step(stmt) != SQLITE_DONE)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
        if(stmt)
            sqlite3_finalize(stmt);
        printf("begin\r\n");
        
        return 0;
    }
    
    int do_test_insert(sqlite3* db)
    {
        const char* create_table_sql = 
                    "insert into testtable values(?,?,?);";
        sqlite3_stmt* stmt = NULL;
        // int len = strlen(create_table_sql);
    
        if(sqlite3_prepare_v2(db, create_table_sql, -1, &stmt, NULL) != SQLITE_OK)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
    
        int insertCount = 10, i = 0;
        const char* strData = "This is a test.";
        printf("start insert \r\n");
        for(i = 0; i < insertCount; i++)
        {
            sqlite3_bind_int(stmt, 1, i);
            sqlite3_bind_double(stmt, 2, i * 1.0);
            sqlite3_bind_text(stmt, 3, strData, strlen(strData), SQLITE_TRANSIENT);
            // printf("%s\n", sqlite3_sql(stmt));
    
            if(sqlite3_step(stmt) != SQLITE_DONE)
            {
                if(stmt)
                    sqlite3_finalize(stmt);
                return -1;
            }
            // printf("%s\n", sqlite3_sql(stmt));
    
            sqlite3_reset(stmt); // 重新初始化 sqlite3_stmt 对象绑定的变量
            printf("insert ok!\r\n");
        }
    
        if(stmt)
        sqlite3_finalize(stmt);
    
        return 0;
    }
    
    int do_test_commit(sqlite3* db)
    {
        const char* create_table_sql = 
                    "commit";
        sqlite3_stmt* stmt = NULL;
        // int len = strlen(create_table_sql);
    
        if(sqlite3_prepare_v2(db, create_table_sql, -1, &stmt, NULL) != SQLITE_OK)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
    
        if(sqlite3_step(stmt) != SQLITE_DONE)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
        if(stmt)
            sqlite3_finalize(stmt);
    
        printf("commit\r\n");
        
        return 0;
    }
    
    int do_test_select(sqlite3* db)
    {
        const char* create_table_sql = 
                    "select * from testtable;";
        sqlite3_stmt* stmt = NULL;
        // int len = strlen(create_table_sql);
    
        if(sqlite3_prepare_v2(db, create_table_sql, -1, &stmt, NULL) != SQLITE_OK)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
    
        int fieldCount = sqlite3_column_count(stmt); // 获取列数
        int i = 0;
    
        while(1)
        {
            int r = sqlite3_step(stmt);
            if(r == SQLITE_ROW) // 执行成功,返回一条结果
            {
                for (i = 0; i < fieldCount; ++i) 
                {
                    int vtype = sqlite3_column_type(stmt, i);
                    if(vtype == SQLITE_INTEGER)
                    {
                        printf("the interger value is %d\n", sqlite3_column_int(stmt, i));
                    }
                    else if(vtype == SQLITE_FLOAT)
                    {
                        printf("the float value is %.2f\n", sqlite3_column_double(stmt, i));
                    }else if(vtype == SQLITE_TEXT)
                    {
                        printf("the text value is %s\n", sqlite3_column_text(stmt, i));
                    }else if(vtype == SQLITE_NULL)
                    {
                        printf("the value is null\n");
                    }
                }
            }
            else if(r == SQLITE_DONE) // 执行成功,没有返回结果
            {
                printf("Select Finished.\n");
                break;
            }
            else 
            {
                if(stmt)
                    sqlite3_finalize(stmt);
                break;
            }
        }
    
        if(stmt)
            sqlite3_finalize(stmt);
        
        return 0;
    }
    
    int do_test_drop(sqlite3* db)
    {
        const char* create_table_sql = 
                    "drop table testtable;";
        sqlite3_stmt* stmt = NULL;
        // int len = strlen(create_table_sql);
    
        if(sqlite3_prepare_v2(db, create_table_sql, -1, &stmt, NULL) != SQLITE_OK)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
    
        if(sqlite3_step(stmt) != SQLITE_DONE)
        {
            if(stmt)
                sqlite3_finalize(stmt);
            return -1;
        }
        if(stmt)
            sqlite3_finalize(stmt);
    
        printf("dropped table testtable!!!\r\n");
        
        return 0;
    }
    
    int do_test_close(sqlite3* db)
    {
        int result = sqlite3_close(db);
        if(result != SQLITE_OK)
        {
            return -1;
        }
        return 0;
    }
    
    
    int main(int argc, char **argv)
    {
        sqlite3* db = do_test_open("test.db"); // 打开数据库,无则创建
    
        do_test_create(db); // 创建表
    
        do_test_select(db); // 查询表
    
        /*使用begin commit来实现高效的多条语句的插入,避免多次的写入内存,减少写入的操作*/
        do_test_begin(db); // 开始执行begin
    
        do_test_insert(db); // 插入表
    
        do_test_commit(db); // commit
    
        do_test_select(db); // 查询表
    
        // do_test_drop(db); // 删除testtable表
    
        do_test_close(db); // 关闭数据库
        
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
  • 相关阅读:
    50道必备的Python面试题 (建议点赞)
    HTTP协议的请求方式有哪些
    VUE3+vite项目中动态引入组件和异步组件
    Leo赠书活动-06期 【强化学习:原理与Python实战】文末送书
    操作系统的主要功能
    格雷码(Gray Code)与8421二进制码之间的转换算法 (LeetCode89)
    打家劫舍 III
    JS中的括号和点号
    .NET 反射 Reflect
    [100天算法】-二叉树剪枝(day 48)
  • 原文地址:https://blog.csdn.net/weixin_45205160/article/details/132815648