首页 数据库 mysql教程 深入SQLite基本操作的总结详解_MySQL

深入SQLite基本操作的总结详解_MySQL

Jun 01, 2016 pm 01:24 PM
access sql语句 接口 数据库

bitsCN.com

sqlite提供的是一些C函数接口,你可以用这些函数操作数据库。通过使用这些接口,传递一些标准 sql 语句(以 char * 类型)给 sqlite 函数,sqlite 就会为你操作数据库。sqlite 跟MS的access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引、触发器等等,但是,它实际上得到的就是一个文件。备份这个文件就备份了整个数据库。 sqlite 不需要任何数据库引擎,这意味着如果你需要 sqlite 来保存一些用户数据,甚至都不需要安装数据库。

下面开始介绍数据库基本操作。
1、基本流程
(1)关键数据结构:
     sqlite 里最常用到的是 sqlite3 * 类型。从数据库打开开始,sqlite就要为这个类型准备好内存,直到数据库关闭,整个过程都需要用到这个类型。当数据库打开时开始,这个类型的变量就代表了你要操作的数据库。下面再详细介绍。
(2)打开数据库:
     int sqlite3_open( 文件名, sqlite3 ** ); 用这个函数开始数据库操作。需要传入两个参数,一是数据库文件名,比如:..//test//testDatabase.db。
文件名不需要一定存在,如果此文件不存在,sqlite 会自动建立它。如果它存在,就尝试把它当数据库文件来打开。 其中sqlite3 ** 参数即前面提到的关键数据结构。这个结构底层细节如何,你不要关它。
    函数返回值表示操作是否正确,如果是 SQLITE_OK 则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可以参考 sqlite3.h 文件。里面有详细定义。
(3)关闭数据库:
    int sqlite3_close(sqlite3 *); 前面如果用 sqlite3_open 开启了一个数据库,结尾时不要忘了用这个函数关闭数据库。
    sqlite数据库操作例子

   #include "./sqlite3.h"
    int main( int , char** )
    {
        sqlite3 * db = NULL; //声明sqlite关键结构指针
        int result;
        //需要传入 db 这个指针的指针,
        //因为 sqlite3_open 函数要为这个指针分配内存,还要让db指针指向这个内存区
        result = sqlite3_open("..//test//testDatabase.db", &db);//打开数据库
        if( result != SQLITE_OK )
        {
            return -1; //数据库打开失败
        }
        //数据库操作代码
        //…-
        //数据库打开成功
        sqlite3_close( db ); //关闭数据库
        return 0;
    }

这就是一次数据库操作过程。

2、 SQL语句操作(如何用sqlite 执行标准 sql 语法)
(1)执行sql语句: int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg ); 这就是执行一条 sql 语句的函数。
 参数说明:
     第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。
     第2个参数const char *sql 是一条 sql 语句,以/0结尾。
     第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
     第4个参数void * 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。
     第5个参数char ** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf("%s/n",errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个 char*得到具体错误提示。
      说明:通常,sqlite3_callback 和它后面的 void * 这两个位置都可以填 NULL。填NULL表示你不需要回调。比如你做 insert 操作,做 delete 操作,就没有必要使用回调。而当你做 select 时,就要使用回调,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。
(2)exec 的回调 :typedef int (*sqlite3_callback)(void*,int,char**, char**); 你的回调函数必须定义成上面这个函数的类型。

sqlite数据库操作例子:

//sqlite3的回调函数
     // sqlite 每查到一条记录,就调用一次这个回调
     //para是你在 sqlite3_exec 里传入的 void * 参数
     //通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然后在这里面强制转换成对应的类型
     //(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据
     //n_column是这一条记录有多少个字段 (即这条记录有多少列)
     //char ** column_value 是关键值,查出来的数据都保存在这里,实际上是个1维数组(不要以为是2维数组),
     //每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以/0结尾)
     //char ** column_name 跟 column_value是对应的,表示这个字段的字段名称     
      int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name )
      {
            //这里,我不使用 para 参数。忽略它的存在.
            int i;
            printf( "记录包含 %d 个字段/n", n_column );
            for( i = 0 ; i             {
                printf( "字段名:%s ?> 字段值:%s/n", column_name[i], column_value[i] );
            }
            printf( "/n" );
            return 0;
      }

      int main( int , char ** )
      {
            sqlite3 * db;
            int result;
            char * errmsg = NULL;
            result = sqlite3_open("..//test//testDatabase.db", &db );
            if( result != SQLITE_OK )
            {
                return -1; //数据库打开失败
            }
            //数据库操作代码
            //创建测试表,表名叫 MyTable_1,有2个字段: ID 和 name。其中ID是一个自动增加的类型,
            //以后insert时可以不去指定这个字段,它会自己从0开始增加            
            result = sqlite3_exec( db, "create table MyTable_1( ID integer primary key autoincrement, name nvarchar(32) ))", NULL, NULL, errmsg );
            if(result != SQLITE_OK )
            {
               printf("创建表失败,错误码:%d,错误原因:%s/n", result, errmsg );
            }
            //插入一些记录
            result = sqlite3_exec( db, "insert into MyTable_1( name) values ('走路')", 0, 0, errmsg); 
            if(result != SQLITE_OK )
          {
             printf( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );
           }

            result = sqlite3_exec( db,"insert into MyTable_1( name ) values ('骑单车')", 0, 0, errmsg);
            if(result != SQLITE_OK )
            {
                printf("插入记录失败,错误码:%d,错误原因:%s/n", result, errmsg );
            }

            result = sqlite3_exec( db, "insert into MyTable_1( name ) values ( '坐汽车')", 0, 0, errmsg );
            if(result != SQLITE_OK )
            {
                printf( "插入记录失败,错误码:%d,错误原因:%s/n", result, errmsg );
            }             
            result = sqlite3_exec( db, "select * from MyTable_1", LoadMyInfo, NULL, errmsg );//开始查询数据库              sqlite3_close( db ); //关闭数据库            
            return 0;
      }

通过上面的例子,应该可以知道如何打开一个数据库,如何做数据库基本操作。
(3)不使用回调查询数据库
     sqlite3_exec 是使用回调来执行 select 操作。还有一个方法可以直接查询而不需要回调。但是,我个人感觉还是回调好,因为代码可以更加整齐,只不过用回调很麻烦,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成 static 的(C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的 sqlite 回调函数的参数不相符。只有当把成员函数声明成 static 时,它才没有多余的隐含的this参数)。虽然回调显得代码整齐,但有时候你还是想要非回调的 select 查询。这可以通过 sqlite3_get_table 函数做到。
    int sqlite3_get_table(sqlite3*, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg );
    参数说明:
    第1个参数不再多说,看前面的例子。
    第2个参数是 sql 语句,跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以/0结尾的char *字符串。
    第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。下面用例子来说事。
    第4个参数是查询出多少条记录(即查出多少行)。
    第5个参数是多少个字段(多少列)。
    第6个参数是错误信息,跟前面一样,这里不多说了。
sqlite数据库操作例子:

 int main( int , char ** )
    {
        sqlite3* db;
        int result;
        char* errmsg = NULL;
        char **dbResult; //是 char ** 类型,两个*号
        int nRow, nColumn;
        int i , j;
        int index;
        result = sqlite3_open("..//test//testDatabase.db", &db );
        if( result != SQLITE_OK )
        {
           return -1; //数据库打开失败
        }
        //数据库操作代码
        //假设前面已经创建了 MyTable_1 表
        //开始查询,传入的 dbResult 已经是 char **,这里又加了一个 & 取地址符,传递进去的就成了 char ***
         result = sqlite3_get_table( db, "select * from MyTable_1", &dbResult, &nRow, &nColumn, &errmsg );
        if( SQLITE_OK == result ) //查询成功
        {
           index = nColumn; //前面说过 dbResult 前面第一行数据是字段名称,从 nColumn 索引开始才是真正的数据
           printf("查到%d条记录/n", nRow );
           for( i = 0; i            {
               printf( "第 %d 条记录/n", i+1 );
               for( j = 0 ; j                {
                 printf("字段名:%s ß> 字段值:%s/n", dbResult[j], dbResult [index]);
                 // dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称
                 // 从第 nColumn 索引开始,后面都是字段值,
                 //它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示
                  ++index;
              }
              printf( "/n" );
          }
       }
       //到这里,不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放
       sqlite3_free_table( dbResult );
       sqlite3_close( db );//关闭数据库
       return 0;
    }
   
到这个例子为止,sqlite3 的常用用法都介绍完了。 用以上的方法,完全可以应付绝大多数数据库需求。

3、事务处理
sqlite 是支持事务处理的。如果你知道你要同步删除很多数据,不仿把它们做成一个统一的事务。通常一次 sqlite3_exec 就是一次事务,如果你要删除1万条数据,sqlite就做了1万次:开始新事务->删除一条数据->提交事务->开始新事务->… 的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。你可以把这些同类操作做成一个事务,这样如果操作错误,还能够回滚事务。事务的操作没有特别的接口函数,它就是一个普通的 sql 语句而已:
分别如下:

int result;
    result = sqlite3_exec( db, "begin transaction", 0, 0, &zErrorMsg ); //开始一个事务
    result = sqlite3_exec( db, "commit transaction", 0, 0, &zErrorMsg ); //提交事务
    result = sqlite3_exec( db, "rollback transaction", 0, 0, &zErrorMsg ); //回滚事务

 

bitsCN.com
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1423
52
Laravel 教程
1318
25
PHP教程
1269
29
C# 教程
1248
24
甲骨文在商业世界中的作用 甲骨文在商业世界中的作用 Apr 23, 2025 am 12:01 AM

Oracle不仅是数据库公司,还是云计算和ERP系统的领导者。1.Oracle提供从数据库到云服务和ERP系统的全面解决方案。2.OracleCloud挑战AWS和Azure,提供IaaS、PaaS和SaaS服务。3.Oracle的ERP系统如E-BusinessSuite和FusionApplications帮助企业优化运营。

MySQL与其他数据库:比较选项 MySQL与其他数据库:比较选项 Apr 15, 2025 am 12:08 AM

MySQL适合Web应用和内容管理系统,因其开源、高性能和易用性而受欢迎。1)与PostgreSQL相比,MySQL在简单查询和高并发读操作上表现更好。2)相较Oracle,MySQL因开源和低成本更受中小企业青睐。3)对比MicrosoftSQLServer,MySQL更适合跨平台应用。4)与MongoDB不同,MySQL更适用于结构化数据和事务处理。

使用DICR/YII2-Google将Google API集成在YII2中 使用DICR/YII2-Google将Google API集成在YII2中 Apr 18, 2025 am 11:54 AM

vProcesserazrabotkiveb被固定,мнелостольностьстьс粹馏标д都LeavallySumballanceFriablanceFaumDoptoMatification,Čtookazalovnetakprosto,kakaožidal.posenesko

MySQL:结构化数据和关系数据库 MySQL:结构化数据和关系数据库 Apr 18, 2025 am 12:22 AM

MySQL通过表结构和SQL查询高效管理结构化数据,并通过外键实现表间关系。1.创建表时定义数据格式和类型。2.使用外键建立表间关系。3.通过索引和查询优化提高性能。4.定期备份和监控数据库确保数据安全和性能优化。

nginx限流怎么解决 nginx限流怎么解决 Apr 14, 2025 pm 12:06 PM

Nginx 限流问题可通过以下方法解决:使用 ngx_http_limit_req_module 限制请求次数;使用 ngx_http_limit_conn_module 限制连接数;使用第三方模块(ngx_http_limit_connections_module、ngx_http_limit_rate_module、ngx_http_access_module)实现更多限流策略;使用云服务(Cloudflare、Google Cloud Rate Limiting、AWS WAF)进行 DD

MySQL:一种对数据存储的初学者友好方法 MySQL:一种对数据存储的初学者友好方法 Apr 17, 2025 am 12:21 AM

MySQL适合初学者,因为它易用且功能强大。1.MySQL是关系型数据库,使用SQL进行CRUD操作。2.安装简单,需配置root用户密码。3.使用INSERT、UPDATE、DELETE、SELECT进行数据操作。4.复杂查询可使用ORDERBY、WHERE和JOIN。5.调试需检查语法,使用EXPLAIN分析查询。6.优化建议包括使用索引、选择合适数据类型和良好编程习惯。

MySQL:解释的关键功能和功能 MySQL:解释的关键功能和功能 Apr 18, 2025 am 12:17 AM

MySQL是一个开源的关系型数据库管理系统,广泛应用于Web开发。它的关键特性包括:1.支持多种存储引擎,如InnoDB和MyISAM,适用于不同场景;2.提供主从复制功能,利于负载均衡和数据备份;3.通过查询优化和索引使用提高查询效率。

怎么在centos搭建minio 怎么在centos搭建minio Apr 14, 2025 pm 04:42 PM

在CentOS上搭建MinIO服务器的步骤如下:1.安装MinIO首先,你需要下载并安装MinIO。你可以从MinIO的官方网站下载最新版本的MinIO二进制文件。wgethttps://dl.min.io/server/minio/release/linux-amd64/miniochmod xminiosudomvminio/usr/local/bin/2.创建Mi

See all articles