zoukankan      html  css  js  c++  java
  • C语言:SQLITE3的学习

    Sqlite基础学习

    一、sqlite的概念

      SQLite是一款轻型数据库,是遵守ACID的关系型数据库管理系统,由C语言开发设计。Sqlite的设计目标着眼于嵌入式领域,所以具有占用系统资源低和处理速度快等特点。

      SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库一样,您不需要在系统中配置。同时sqlite没有额外依赖并且完全开源,同时其源码拥有大量注释,可读性非常好。

    二、Sqlite的用途

    Sqlite支持跨平台,操作简单,能够使用很多语言直接创建数据库。如果你需要做一个很小型的应用,或者你想做嵌入式开发,没有合适的数据库系统,那么你可以考虑使用SQLite。例如android系统,IOS系统等都采用了SQLite做为数据库。

    三、Sqlite语法简介

    1SQL简介

      SQL 是用于访问和处理数据库的标准的计算机语言。对于sqlite、mysql、sqlserver等数据库的操作语言都需要遵循SQL的规范,不过不同的数据库系统可能对SQL规范作了某些编改和扩充,所以不同数据库系统之间的SQL不能完全相互通用。

      SQL的一些基本操作:

    (1)、面向数据库执行查询或取出数据

    (2)、往数据库中插入新的记录

    (3)、更新数据库中的数据

    (4)、从数据库删除记录

    (5)、建新数据库

    (6)、在数据库中创建新表

      其相对应的操作语法大致如下:(以下只是列举一些语法,并不做说明)

    (1)、(SELECT 列名称 FROM 表名称),(SELECT DISTINCT 列名称 FROM 表 名称),(SELECT 列名称 FROM 表名称 WHERE 列 运算符 值),

    (SELECT 列名称1 列名称2 FROM 表名称 ORDER BY 列名称1)等等。

    (2)、( INSERT INTO 表名称 VALUES (值1, 值2,....)),

    (INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....))等。

    (3)、(UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值)等。

    (4)、(DELETE FROM 表名称 WHERE 列名称 = 值)等。

    (5)、(CREATE DATABASE database_name)等。

    (6)、CREATE TABLE 表名称

    (

    列名称1 数据类型,

    列名称2 数据类型,

    列名称3 数据类型,

    ....

    )

    2Sqlite3常用函数说明

    SQLITE_API int sqlite3_open(
      const char *filename,   /* Database filename (UTF-8) */
      sqlite3 **ppDb          /* OUT: SQLite db handle */
    );
    函数说明:该程序会通过指定的文件名参数打开一个数据库文件
    数据库的连接返回到*ppDb,函数的返回值代表了操作状态,例如成功
    就返回SQLITE_OK,否则返回错误代码和意外情况下不能分配内存来的得到
    sqlite3就返回NULL

    SQLITE_API int sqlite3_close(sqlite3*);
    函数说明:前面如果用 sqlite3_open 开启了一个数据库,结尾时不要忘了用这个函数关闭数据库
    同样返回值为操作状态

    SQLITE_API int sqlite3_exec(
      sqlite3*,                                  /* An open database */
      const char *sql,                           /* SQL to be evaluated */
      int (*callback)(void*,int,char**,char**),  /* Callback function */
      void *,                                    /* 1st argument to callback */
      char **errmsg                              /* Error msg written here */
    );
    函数说明:该函数为具体执行SQL语句的函数
    参数1:打开的数据库连接对象
    参数2:传入的SQL语句,以‘/0’结尾
    参数3:是回调函数,如果传入参数不为NULL,则得到一个结果行就会调用该回调函数
    参数4:自定义的一个指针,目的是传入到回调函数参数以供使用。
    参数5:错误信息,如果语句执行失败,就可以查阅该指针,这里的参数是输出特性
        (即主调函数将类型变量的地址传入,函数分配内存赋值给该变量)
        同时在执行完该函数后又不需要错误信息时,为了避免内存泄露,应该调用
        sqlite3_free()来释放这块内存
    返回值:操作状态

    SQLITE_API 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 */
    );
    函数说明:与sqlite3_exec功能相同,只是不使用回调函数而是直接一张表的内存和行与列
    参数1:打开的数据库连接对象
    参数2:该参数为输出特性,目的是函数内部返回一张表给主调函数使用,最终使用完需要
        释放是,不能调用 sqlite3_free() 而是要调用 sqlite3_free_table()来做释放
    参数3:该参数为输出特性,修改pnRow的值为表的行数
    参数4:该参数为输出特性,修改pnColumn的值为表的列数
    参数5:错误信息,如果语句执行失败,就可以查阅该指针,这里的参数是输出特性
        同时在执行完该函数后又不需要错误信息时,为了避免内存泄露,应该调用
        sqlite3_free()来释放这块内存
    返回值:操作状态

    这些是比较常用的函数,至于更多的函数则不在多举例。

    四、sqlite3使用例子

        1、操作数据库的一个简单例子(代码参考自别人)

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sqlite3.h>
    static int loadMyInfo(void* para, int column, char** columnValue,char** columnName)
    {
        int i = 0;
        for (i = 0; i < column; i++)
        {
            printf("field name:%s    ------>        field values:%s
    ", columnName[i],columnValue[i]);
        }
        printf("------------------------------------------------------
    ");
        return 0;
    }
    int main(void)
    {
        sqlite3 *db = NULL;
        int result;
        char *errMsg = NULL;
        //打开数据库
        //传如sqlite3*类型变量的地址
        result = sqlite3_open("/home/sns/workspace/database.db", &db);
        if (result != SQLITE_OK)
        {
            printf("database open fail!
    ");
            return -1;
        }
        //TODO    数据库操作代码
        //sqlite的操作语句不区分大小写
        //创建一个数据表,表名为MyTabale1,分两个字段:ID和name。
        //其中ID是一个自动增加的整型,之后insert可以不去指定这个字段,它会自己从0开始增加
        //name为一个含 32 个字符的可变长度 Unicode 字符数据.
        result =sqlite3_exec(db,
                        "create table MyTable1(ID Integer primary key autoincrement,name nvarchar(32))",
                        NULL, NULL, &errMsg);    //(字段名 字段类型 SQL约束)
        if (result != SQLITE_OK)
        {
            printf("create a table fail!,fail code:%d,fail reason:%s
    ", result,
                    errMsg);
        }
        if (errMsg != NULL)
        {
            sqlite3_free(errMsg);
            errMsg = NULL;
        }
        //往表中插入三条记录
        result = sqlite3_exec(db, "insert into MyTable1(name) values('zoulu')",NULL, NULL, &errMsg);
        if (result != SQLITE_OK)
        {
            printf("insert a record fail!,fail code:%d,fail reason:%s
    ", result,
                    errMsg);
        }
        if (errMsg != NULL)
        {
            sqlite3_free(errMsg);
            errMsg = NULL;
        }
        result = sqlite3_exec(db, "insert into MyTable1(name) values('qidanche')",NULL, NULL, &errMsg);
        if (result != SQLITE_OK)
        {
            printf("create a record fail!,fail code:%d,fail reason:%s
    ", result,
                    errMsg);
        }
        if (errMsg != NULL)
        {
            sqlite3_free(errMsg);
            errMsg = NULL;
        }
        result = sqlite3_exec(db, "insert into MyTable1(name) values('zuofeiji')",
                NULL, NULL, &errMsg);
        if (result != SQLITE_OK)
        {
            printf("create a record fail!,fail code:%d,fail reason:%s
    ", result,
                    errMsg);
        }
        if (errMsg != NULL)
        {
            sqlite3_free(errMsg);
            errMsg = NULL;
        }
    //    查询数据库
        result = sqlite3_exec(db, "select * from MyTable1", loadMyInfo, NULL,&errMsg);
        if (errMsg != NULL)
        {
            sqlite3_free(errMsg);
            errMsg = NULL;
        }
    
        //不使用回调函数查询数据库
        char **dbResult = NULL;
        int nRow, nColumn;
        int index;
        int i, j;
        result = sqlite3_get_table(db, "select * from MyTable1", &dbResult, &nRow,&nColumn, &errMsg);
        if (result == SQLITE_OK)
        {
            index = nColumn;
            printf("find %d record
    ", nRow);
    
            for (i = 0; i < nRow; i++)
            {
                for (j = 0; j < nColumn; j++)
                {
                    printf("field name:%s    ------>        field values:%s
    ", dbResult[j],
                            dbResult[index]);
                    index++;
                }
                printf(
                        "----------------------------------------------------------
    ");
            }
        }
    
        sqlite3_free_table(dbResult);
        //关闭数据库
        sqlite3_close(db);
        return EXIT_SUCCESS;
    }
    code1

         2、存取和读出二进制数据

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sqlite3.h>
    //sqlite 存取和读出二进制数据,需要使用sqlite3的sqlite3_stmt
    int main(void)
    {
        sqlite3 *db1 = NULL;
        char *errMsg=NULL;//保存错误信息
        int result = 0;
        result = sqlite3_open("/home/sns/workspace/binarydatabase.db",&db1);
        if(result!=SQLITE_OK)
        {
            printf("database open fail!
    ");
            return -1;
        }
        //数据库操作 :
        result = sqlite3_exec(db1,"create table BinTable2(ID integer,content blob)",NULL,NULL,&errMsg);
        if(result != SQLITE_OK)
        {
            printf("create a table fail!,fail code:%d fail reason:%s",result,errMsg);
            return -1;
        }
        //写入二进制内容
        sqlite3_stmt *stat;
        void *pdata="hjktgagagf";
        result = sqlite3_prepare( db1, "insert into BinTable2( ID, content) values( 10, ? )", -1, &stat, 0 );
        if(result == SQLITE_OK && stat!=NULL)
        {
            sqlite3_bind_blob(stat,1,pdata,sizeof(pdata),NULL);
            printf("pdata length:%ld
    ",sizeof(pdata));
            result= sqlite3_step(stat);
            if(result!=SQLITE_OK)
            {
                printf("write fail!
    ");
            }
        }
        if(stat)
        {
            sqlite3_finalize(stat);
        }
        //读出数据库记录
        sqlite3_stmt *stat1=NULL;
        result = sqlite3_prepare( db1, "select * from BinTable2", -1, &stat1, 0 );
        if(result==SQLITE_OK)
        {
                result = sqlite3_step(stat1);
                printf("result:    %d
    ",result);
                if(result==SQLITE_ROW)
                {
                    int id = sqlite3_column_int(stat1,0);
                    const void * content = sqlite3_column_blob(stat1,1);
                    int len = sqlite3_column_bytes(stat1,1);
                    printf("
    id = %d,sizeof(content) = %d !
    ",id,len);
                }
        }
        if(stat1)
        {
            sqlite3_finalize(stat1);
        }
        //关闭数据库
        sqlite3_close(db1);
        return EXIT_SUCCESS;
    }
    code2

     五:扩展说明

      关于sqlite3的C语言使用可以更多的关注该作者:https://home.cnblogs.com/u/elect-fans/

      本文第四项的操作二进制代码的说明请参考

        基于SQLITE数据库的C语言编程

  • 相关阅读:
    图解Http协议 url长度限制
    cpu占用工具,亲测可用
    python使用mysql 获取数据,感知不到数据变化的原因
    dns压测工具dnsperf
    sqlalchemy.exc.ArgumentError: Mapper mapped class Result->result could not assemble any primary key 报错解决
    DevTools failed to load SourceMap: Could not load content for chrome-extension 解决
    tcp/udp 的一些测试
    win端 vscode 远程连接 centos,配置调试
    gitllab访问报错:Permission denied (publickey). 以及后续测试
    linux文件表项测试
  • 原文地址:https://www.cnblogs.com/xishuichangliu/p/6270291.html
Copyright © 2011-2022 走看看