深刻SQLite根本操作的總結詳解。本站提示廣大學習愛好者:(深刻SQLite根本操作的總結詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻SQLite根本操作的總結詳解正文
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 < 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; //數據庫翻開掉敗
}
//數據庫操作代碼
//創立測試表,表名叫 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 < nRow ; i++ )
{
printf( "第 %d 筆記錄\n", i+1 );
for( j = 0 ; j < nColumn; 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 ); //回滾事務