青草久久影院-青草久久伊人-青草久久久-青草久久精品亚洲综合专区-SM双性精跪趴灌憋尿调教H-SM脚奴调教丨踩踏贱奴

17站長(zhǎng)網(wǎng)

深入SQLite基本操作的總結(jié)詳解

2023-3-21 15:23| 查看: 2094 |來(lái)源: 互聯(lián)網(wǎng)

sqlite提供的是一些C函數(shù)接口,你可以用這些函數(shù)操作數(shù)據(jù)庫(kù)。通過(guò)使用這些接口,傳遞一些標(biāo)準(zhǔn) sql 語(yǔ)句(以 char * 類型)給 sqlite 函數(shù),sqlite 就會(huì)為你操作 ...

sqlite提供的是一些C函數(shù)接口,你可以用這些函數(shù)操作數(shù)據(jù)庫(kù)。通過(guò)使用這些接口,傳遞一些標(biāo)準(zhǔn) sql 語(yǔ)句(以 char * 類型)給 sqlite 函數(shù),sqlite 就會(huì)為你操作數(shù)據(jù)庫(kù)。sqlite 跟MS的access一樣是文件型數(shù)據(jù)庫(kù),就是說(shuō),一個(gè)數(shù)據(jù)庫(kù)就是一個(gè)文件,此數(shù)據(jù)庫(kù)里可以建立很多的表,可以建立索引、觸發(fā)器等等,但是,它實(shí)際上得到的就是一個(gè)文件。備份這個(gè)文件就備份了整個(gè)數(shù)據(jù)庫(kù)。 sqlite 不需要任何數(shù)據(jù)庫(kù)引擎,這意味著如果你需要 sqlite 來(lái)保存一些用戶數(shù)據(jù),甚至都不需要安裝數(shù)據(jù)庫(kù)。

下面開(kāi)始介紹數(shù)據(jù)庫(kù)基本操作。

1、基本流程

(1)關(guān)鍵數(shù)據(jù)結(jié)構(gòu):

sqlite 里最常用到的是 sqlite3 * 類型。從數(shù)據(jù)庫(kù)打開(kāi)開(kāi)始,sqlite就要為這個(gè)類型準(zhǔn)備好內(nèi)存,直到數(shù)據(jù)庫(kù)關(guān)閉,整個(gè)過(guò)程都需要用到這個(gè)類型。當(dāng)數(shù)據(jù)庫(kù)打開(kāi)時(shí)開(kāi)始,這個(gè)類型的變量就代表了你要操作的數(shù)據(jù)庫(kù)。下面再詳細(xì)介紹。

(2)打開(kāi)數(shù)據(jù)庫(kù):

int sqlite3_open( 文件名, sqlite3 ** ); 用這個(gè)函數(shù)開(kāi)始數(shù)據(jù)庫(kù)操作。需要傳入兩個(gè)參數(shù),一是數(shù)據(jù)庫(kù)文件名,比如:..//test//testDatabase.db。

文件名不需要一定存在,如果此文件不存在,sqlite 會(huì)自動(dòng)建立它。如果它存在,就嘗試把它當(dāng)數(shù)據(jù)庫(kù)文件來(lái)打開(kāi)。 其中sqlite3 ** 參數(shù)即前面提到的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。這個(gè)結(jié)構(gòu)底層細(xì)節(jié)如何,你不要關(guān)它。

函數(shù)返回值表示操作是否正確,如果是 SQLITE_OK 則表示操作正常。相關(guān)的返回值sqlite定義了一些宏。具體這些宏的含義可以參考 sqlite3.h 文件。里面有詳細(xì)定義。

(3)關(guān)閉數(shù)據(jù)庫(kù):

int sqlite3_close(sqlite3 *); 前面如果用 sqlite3_open 開(kāi)啟了一個(gè)數(shù)據(jù)庫(kù),結(jié)尾時(shí)不要忘了用這個(gè)函數(shù)關(guān)閉數(shù)據(jù)庫(kù)。

sqlite數(shù)據(jù)庫(kù)操作例子

復(fù)制代碼 代碼如下:www.CuoXin.com

#include "./sqlite3.h"

int main( int , char** )

{

sqlite3 * db = NULL; //聲明sqlite關(guān)鍵結(jié)構(gòu)指針

int result;

//需要傳入 db 這個(gè)指針的指針,

//因?yàn)?sqlite3_open 函數(shù)要為這個(gè)指針?lè)峙鋬?nèi)存,還要讓db指針指向這個(gè)內(nèi)存區(qū)

result = sqlite3_open("..//test//testDatabase.db", &db);//打開(kāi)數(shù)據(jù)庫(kù)

if( result != SQLITE_OK )

{

return -1; //數(shù)據(jù)庫(kù)打開(kāi)失敗

}

//數(shù)據(jù)庫(kù)操作代碼

//…-

//數(shù)據(jù)庫(kù)打開(kāi)成功

sqlite3_close( db ); //關(guān)閉數(shù)據(jù)庫(kù)

return 0;

}

這就是一次數(shù)據(jù)庫(kù)操作過(guò)程。

2、 SQL語(yǔ)句操作(如何用sqlite 執(zhí)行標(biāo)準(zhǔn) sql 語(yǔ)法)

(1)執(zhí)行sql語(yǔ)句: int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg ); 這就是執(zhí)行一條 sql 語(yǔ)句的函數(shù)。

參數(shù)說(shuō)明:

第1個(gè)參數(shù)不再說(shuō)了,是前面open函數(shù)得到的指針。說(shuō)了是關(guān)鍵數(shù)據(jù)結(jié)構(gòu)。

第2個(gè)參數(shù)const char *sql 是一條 sql 語(yǔ)句,以/0結(jié)尾。

第3個(gè)參數(shù)sqlite3_callback 是回調(diào),當(dāng)這條語(yǔ)句執(zhí)行之后,sqlite3會(huì)去調(diào)用你提供的這個(gè)函數(shù)。

第4個(gè)參數(shù)void * 是你所提供的指針,你可以傳遞任何一個(gè)指針參數(shù)到這里,這個(gè)參數(shù)最終會(huì)傳到回調(diào)函數(shù)里面,如果不需要傳遞指針給回調(diào)函數(shù),可以填NULL。等下我們?cè)倏椿卣{(diào)函數(shù)的寫法,以及這個(gè)參數(shù)的使用。

第5個(gè)參數(shù)char ** errmsg 是錯(cuò)誤信息。注意是指針的指針。sqlite3里面有很多固定的錯(cuò)誤信息。執(zhí)行 sqlite3_exec 之后,執(zhí)行失敗時(shí)可以查閱這個(gè)指針(直接 printf("%s/n",errmsg))得到一串字符串信息,這串信息告訴你錯(cuò)在什么地方。sqlite3_exec函數(shù)通過(guò)修改你傳入的指針的指針,把你提供的指針指向錯(cuò)誤提示信息,這樣sqlite3_exec函數(shù)外面就可以通過(guò)這個(gè) char*得到具體錯(cuò)誤提示。

說(shuō)明:通常,sqlite3_callback 和它后面的 void * 這兩個(gè)位置都可以填 NULL。填NULL表示你不需要回調(diào)。比如你做 insert 操作,做 delete 操作,就沒(méi)有必要使用回調(diào)。而當(dāng)你做 select 時(shí),就要使用回調(diào),因?yàn)?sqlite3 把數(shù)據(jù)查出來(lái),得通過(guò)回調(diào)告訴你查出了什么數(shù)據(jù)。

(2)exec 的回調(diào) :typedef int (*sqlite3_callback)(void*,int,char**, char**); 你的回調(diào)函數(shù)必須定義成上面這個(gè)函數(shù)的類型。

sqlite數(shù)據(jù)庫(kù)操作例子:

復(fù)制代碼 代碼如下:www.CuoXin.com

//sqlite3的回調(diào)函數(shù)

// sqlite 每查到一條記錄,就調(diào)用一次這個(gè)回調(diào)

//para是你在 sqlite3_exec 里傳入的 void * 參數(shù)

//通過(guò)para參數(shù),你可以傳入一些特殊的指針(比如類指針、結(jié)構(gòu)指針),然后在這里面強(qiáng)制轉(zhuǎn)換成對(duì)應(yīng)的類型

//(這里面是void*類型,必須強(qiáng)制轉(zhuǎn)換成你的類型才可用)。然后操作這些數(shù)據(jù)

//n_column是這一條記錄有多少個(gè)字段 (即這條記錄有多少列)

//char ** column_value 是關(guān)鍵值,查出來(lái)的數(shù)據(jù)都保存在這里,實(shí)際上是個(gè)1維數(shù)組(不要以為是2維數(shù)組),

//每一個(gè)元素都是一個(gè) char * 值,是一個(gè)字段內(nèi)容(用字符串來(lái)表示,以/0結(jié)尾)

//char ** column_name 跟 column_value是對(duì)應(yīng)的,表示這個(gè)字段的字段名稱

int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name )

{

//這里,我不使用 para 參數(shù)。忽略它的存在.

int i;

printf( "記錄包含 %d 個(gè)字段/n", n_column );

for( i = 0 ; i < n_column; 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; //數(shù)據(jù)庫(kù)打開(kāi)失敗

}

//數(shù)據(jù)庫(kù)操作代碼

//創(chuàng)建測(cè)試表,表名叫 MyTable_1,有2個(gè)字段: ID 和 name。其中ID是一個(gè)自動(dòng)增加的類型,

//以后insert時(shí)可以不去指定這個(gè)字段,它會(huì)自己從0開(kāi)始增加

result = sqlite3_exec( db, "create table MyTable_1( ID integer primary key autoincrement, name nvarchar(32) ))", NULL, NULL, errmsg );

if(result != SQLITE_OK )

{

printf("創(chuàng)建表失敗,錯(cuò)誤碼:%d,錯(cuò)誤原因:%s/n", result, errmsg );

}

//插入一些記錄

result = sqlite3_exec( db, "insert into MyTable_1( name) values ('走路')", 0, 0, errmsg);

if(result != SQLITE_OK )

{

printf( “插入記錄失敗,錯(cuò)誤碼:%d,錯(cuò)誤原因:%s/n”, result, errmsg );

}

result = sqlite3_exec( db,"insert into MyTable_1( name ) values ('騎單車')", 0, 0, errmsg);

if(result != SQLITE_OK )

{

printf("插入記錄失敗,錯(cuò)誤碼:%d,錯(cuò)誤原因:%s/n", result, errmsg );

}

result = sqlite3_exec( db, "insert into MyTable_1( name ) values ( '坐汽車')", 0, 0, errmsg );

if(result != SQLITE_OK )

{

printf( "插入記錄失敗,錯(cuò)誤碼:%d,錯(cuò)誤原因:%s/n", result, errmsg );

}

result = sqlite3_exec( db, "select * from MyTable_1", LoadMyInfo, NULL, errmsg );//開(kāi)始查詢數(shù)據(jù)庫(kù) sqlite3_close( db ); //關(guān)閉數(shù)據(jù)庫(kù)

return 0;

}

通過(guò)上面的例子,應(yīng)該可以知道如何打開(kāi)一個(gè)數(shù)據(jù)庫(kù),如何做數(shù)據(jù)庫(kù)基本操作。

(3)不使用回調(diào)查詢數(shù)據(jù)庫(kù)

sqlite3_exec 是使用回調(diào)來(lái)執(zhí)行 select 操作。還有一個(gè)方法可以直接查詢而不需要回調(diào)。但是,我個(gè)人感覺(jué)還是回調(diào)好,因?yàn)榇a可以更加整齊,只不過(guò)用回調(diào)很麻煩,你得聲明一個(gè)函數(shù),如果這個(gè)函數(shù)是類成員函數(shù),你還不得不把它聲明成 static 的(C++成員函數(shù)實(shí)際上隱藏了一個(gè)參數(shù):this,C++調(diào)用類的成員函數(shù)的時(shí)候,隱含把類指針當(dāng)成函數(shù)的第一個(gè)參數(shù)傳遞進(jìn)去。結(jié)果,這造成跟前面說(shuō)的 sqlite 回調(diào)函數(shù)的參數(shù)不相符。只有當(dāng)把成員函數(shù)聲明成 static 時(shí),它才沒(méi)有多余的隱含的this參數(shù))。雖然回調(diào)顯得代碼整齊,但有時(shí)候你還是想要非回調(diào)的 select 查詢。這可以通過(guò) sqlite3_get_table 函數(shù)做到。

int sqlite3_get_table(sqlite3*, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg );

參數(shù)說(shuō)明:

第1個(gè)參數(shù)不再多說(shuō),看前面的例子。

第2個(gè)參數(shù)是 sql 語(yǔ)句,跟 sqlite3_exec 里的 sql 是一樣的。是一個(gè)很普通的以/0結(jié)尾的char *字符串。

第3個(gè)參數(shù)是查詢結(jié)果,它依然一維數(shù)組(不要以為是二維數(shù)組,更不要以為是三維數(shù)組)。它內(nèi)存布局是:第一行是字段名稱,后面是緊接著是每個(gè)字段的值。下面用例子來(lái)說(shuō)事。

第4個(gè)參數(shù)是查詢出多少條記錄(即查出多少行)。

第5個(gè)參數(shù)是多少個(gè)字段(多少列)。

第6個(gè)參數(shù)是錯(cuò)誤信息,跟前面一樣,這里不多說(shuō)了。

sqlite數(shù)據(jù)庫(kù)操作例子:

復(fù)制代碼 代碼如下:www.CuoXin.com

int main( int , char ** )

{

sqlite3* db;

int result;

char* errmsg = NULL;

char **dbResult; //是 char ** 類型,兩個(gè)*號(hào)

int nRow, nColumn;

int i , j;

int index;

result = sqlite3_open("..//test//testDatabase.db", &db );

if( result != SQLITE_OK )

{

return -1; //數(shù)據(jù)庫(kù)打開(kāi)失敗

}

//數(shù)據(jù)庫(kù)操作代碼

//假設(shè)前面已經(jīng)創(chuàng)建了 MyTable_1 表

//開(kāi)始查詢,傳入的 dbResult 已經(jīng)是 char **,這里又加了一個(gè) & 取地址符,傳遞進(jìn)去的就成了 char ***

result = sqlite3_get_table( db, "select * from MyTable_1", &dbResult, &nRow, &nColumn, &errmsg );

if( SQLITE_OK == result ) //查詢成功

{

index = nColumn; //前面說(shuō)過(guò) dbResult 前面第一行數(shù)據(jù)是字段名稱,從 nColumn 索引開(kāi)始才是真正的數(shù)據(jù)

printf("查到%d條記錄/n", nRow );

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]);

// dbResult 的字段值是連續(xù)的,從第0索引到第 nColumn - 1索引都是字段名稱

// 從第 nColumn 索引開(kāi)始,后面都是字段值,

//它把一個(gè)二維的表(傳統(tǒng)的行列表示法)用一個(gè)扁平的形式來(lái)表示

++index;

}

printf( "/n" );

}

}

//到這里,不論數(shù)據(jù)庫(kù)查詢是否成功,都釋放 char** 查詢結(jié)果,使用 sqlite 提供的功能來(lái)釋放

sqlite3_free_table( dbResult );

sqlite3_close( db );//關(guān)閉數(shù)據(jù)庫(kù)

return 0;

}

到這個(gè)例子為止,sqlite3 的常用用法都介紹完了。 用以上的方法,完全可以應(yīng)付絕大多數(shù)數(shù)據(jù)庫(kù)需求。

3、事務(wù)處理

sqlite 是支持事務(wù)處理的。如果你知道你要同步刪除很多數(shù)據(jù),不仿把它們做成一個(gè)統(tǒng)一的事務(wù)。通常一次 sqlite3_exec 就是一次事務(wù),如果你要?jiǎng)h除1萬(wàn)條數(shù)據(jù),sqlite就做了1萬(wàn)次:開(kāi)始新事務(wù)->刪除一條數(shù)據(jù)->提交事務(wù)->開(kāi)始新事務(wù)->… 的過(guò)程。這個(gè)操作是很慢的。因?yàn)闀r(shí)間都花在了開(kāi)始事務(wù)、提交事務(wù)上。你可以把這些同類操作做成一個(gè)事務(wù),這樣如果操作錯(cuò)誤,還能夠回滾事務(wù)。事務(wù)的操作沒(méi)有特別的接口函數(shù),它就是一個(gè)普通的 sql 語(yǔ)句而已:

分別如下:

復(fù)制代碼 代碼如下:www.CuoXin.com

int result;

result = sqlite3_exec( db, "begin transaction", 0, 0, &zErrorMsg ); //開(kāi)始一個(gè)事務(wù)

result = sqlite3_exec( db, "commit transaction", 0, 0, &zErrorMsg ); //提交事務(wù)

result = sqlite3_exec( db, "rollback transaction", 0, 0, &zErrorMsg ); //回滾事務(wù)

本文最后更新于 2023-3-21 15:23,某些文章具有時(shí)效性,若有錯(cuò)誤或已失效,請(qǐng)?jiān)诰W(wǎng)站留言或聯(lián)系站長(zhǎng):[email protected]
·END·
站長(zhǎng)網(wǎng)微信號(hào):w17tui,關(guān)注站長(zhǎng)、創(chuàng)業(yè)、關(guān)注互聯(lián)網(wǎng)人 - 互聯(lián)網(wǎng)創(chuàng)業(yè)者營(yíng)銷服務(wù)中心

免責(zé)聲明:本站部分文章和圖片均來(lái)自用戶投稿和網(wǎng)絡(luò)收集,旨在傳播知識(shí),文章和圖片版權(quán)歸原作者及原出處所有,僅供學(xué)習(xí)與參考,請(qǐng)勿用于商業(yè)用途,如果損害了您的權(quán)利,請(qǐng)聯(lián)系我們及時(shí)修正或刪除。謝謝!

17站長(zhǎng)網(wǎng)微信二維碼

始終以前瞻性的眼光聚焦站長(zhǎng)、創(chuàng)業(yè)、互聯(lián)網(wǎng)等領(lǐng)域,為您提供最新最全的互聯(lián)網(wǎng)資訊,幫助站長(zhǎng)轉(zhuǎn)型升級(jí),為互聯(lián)網(wǎng)創(chuàng)業(yè)者提供更加優(yōu)質(zhì)的創(chuàng)業(yè)信息和品牌營(yíng)銷服務(wù),與站長(zhǎng)一起進(jìn)步!讓互聯(lián)網(wǎng)創(chuàng)業(yè)者不再孤獨(dú)!

掃一掃,關(guān)注站長(zhǎng)網(wǎng)微信

大家都在看

熱門排行

最近更新

返回頂部
主站蜘蛛池模板: www红色一片 | 野花韩国免费高清电影 | 视频一区视频二区在线观看 | 亚洲色欲国产免费视频 | 成人免费视频在线看 | 99爱在线观看| 国产精品久久人妻拍拍水牛影视 | 丰满人妻按磨HD | 久在线观看福利视频 | 欧美日韩在线成人看片a | 国产成人无码精品久久久免费69 | 国产精品无需播放器 | 四虎精品久久 | 国产成人h在线视频 | 国产亚洲日韩在线播放不卡 | 一区三区在线专区在线 | 久久re这里视频精品15 | 九九热精品视频在线观看 | 91偷偷久久做嫩草电影院 | 中文字幕绝色少妇性 | 无码人妻丰满熟妇区五十路久久 | 成人午夜精品无码区久久漫画日本 | 2021扫黑风暴在线观看免费完整版 | 久久www99re在线播放 | 麻豆啊传媒app黄版破解免费 | 97色伦图片97色伦图影院久久 | 电影果冻传媒在线播放 | 76人遣返航班上71人呈阳性 | 午夜福利网国产A | 亚洲AV电影天堂男人的天堂 | 人妻中文字幕无码久久AV爆 | 国产国产成年在线视频区 | 欧美午夜免费观看福利片 | 欧美日韩精品一区二区三区高清视频 | 大香网伊人久久综合观看 | 撕开美女的衣服2 | 日本另类xxxx | 国产亚洲精品久久777777 | 国产精品你懂得 | 99精品国产在热 | 午夜福利免费视频921000电影 |