首頁 資料庫 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

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++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教程
1268
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 18, 2025 am 12:17 AM

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。

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.優化建議包括使用索引、選擇合適數據類型和良好編程習慣。

怎麼在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