SQLITE使用(三)&&核心API使用

来源:http://www.cnblogs.com/cchust/archive/2016/01/12/5121559.html
-Advertisement-
Play Games

概述 SQLite提供了一系列介面供用戶訪問資料庫,主要包括連接資料庫,處理SQL,迭代查詢結果等。本文會針對我們使用SQLite的主要場景,列出核心的API,詳細介紹API的用法並給出代碼用例。1.打開關閉資料庫sqlite3_open_v2原型:int sqlite3_open_v2(cons....


概述
     SQLite提供了一系列介面供用戶訪問資料庫,主要包括連接資料庫,處理SQL,迭代查詢結果等。本文會針對我們使用SQLite的主要場景,列出核心的API,詳細介紹API的用法並給出代碼用例。
1.打開關閉資料庫
sqlite3_open_v2
原型:

int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);

作用:打開一個資料庫連接
關鍵的參數:flags
SQLITE_OPEN_NOMUTEX: 設置資料庫連接運行在多線程模式(沒有指定單線程模式的情況下)
SQLITE_OPEN_FULLMUTEX:設置資料庫連接運行在串列模式。
SQLITE_OPEN_SHAREDCACHE:設置運行在共用緩存模式。
SQLITE_OPEN_PRIVATECACHE:設置運行在非共用緩存模式。
SQLITE_OPEN_READWRITE:指定資料庫連接可以讀寫。
SQLITE_OPEN_CREATE:如果資料庫不存在,則創建。

sqlite3_close_v2
原型:

int sqlite3_close_v2(sqlite3*);

作用:關閉資料庫連接,若關閉時連接上有未提交的事務,該事務會自動回滾。

1.1 例子:打開關閉資料庫連接

sqlite3* pDb;
char* filename="/u01/sqlite/test.db";
sqlite3_open_v2(filename, &pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE, NULL);
....
....
sqlite3_close_v2(pDb);

打開資料庫文件test.db,對應的資料庫連接可讀可寫,以多線程模式運行,並且運行在共用緩存模式,執行完操作後,關閉資料庫連接。

2.更新SQL
更新SQL主要包括創建表,插入,刪除,更新記錄等,SQLite中常用的更新API有兩個,一個是sqlite3_exec,另外一個是sqlite3_prepare_v2。

2.1 sqlite3_exec
原型:

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可以包含多個SQL命令,語句之間以分號隔開,sqlite3_exec()將解析和執行sql字元串中的每個命令,直到到達該字元串的末尾或遇到錯誤。對於運行修改資料庫的命令(創建,插入,刪除,更新)非常適合,一個函數調用就可以完成全部操作。需要註意的是,雖然sqlite3_exec()可以執行多個SQL命令,但是函數不保證事務,即已執行成功的語句,不會因為後面執行失敗的語句而回滾。

2.2 sqlite3_perpare_v2
原型:

int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);

sqlite3_exec實際上是將編譯,執行進行了封裝,與之等價的一組函數是 sqlite3_prepare_v2(), sqlite3_step()和sqlite3_finalize()。sqlite3_prepare_v2()編譯SQL語句生成VDBE執行碼,sqlite3_step()執行,sqlite3_finalize()關閉語句句柄,釋放資源。兩種方式,都可以通過調用sqlite3_changes(pdb),得到語句影響的行數。

2.3兩種方式比較
(1).sqlite3_exec方式介面使用很簡單,實現同樣的功能,比sqlite3_perpare_v2介面代碼量少。
(2).sqlite3_prepare方式更高效,因為只需要編譯一次,就可以重覆執行N次。
(3).sqlite3_prepare方式支持參數化SQL。

鑒於兩種方式的差異,對於簡單的PRAGMA設置語句(PRAGMA cache_size=2000),事務設置語句(BEGIN TRANSACTION,COMMIT,ROLLBACK)使用sqlite3_exec方式,更簡單;而對於批量的更新、查詢語句,則使用sqlite3_prepare方式,更高效。

2.4 例子:prepare方式執行多sql的例子,pNext初始化在sql語句首部,執行完一個sql後,移動到下一個sql首部。

const char *pNext = (const char *)sql;
while (pNext && strlen(pNext) > 0) {
  rc = sqlite3_prepare_v2(pDb, pNext, -1, &pStmt, &pNext);
  if(SQLITE_OK != rc){
    錯誤處理
    break;
  }
   
rc
= sqlite3_step(pStmt); if(SQLITE_OK != rc && SQLITE_DONE != rc){    錯誤處理    break; }
rc = SQLITE_OK;

/*統計影響記錄數目*/
resultCount += sqlite3_changes(pDb);

/* 清理語句句柄,準備執行下一個語句*/ sqlite3_finalize(pStmt); }

3.查詢SQL
3.1 sqlite3_get_table
原型:

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 */
);

該函數接收SQL語句返回的所有記錄,使用sqlite內部分配的記憶體,將其存儲在參數resultp中,必須使用sqlite3_free_table()釋放記憶體。由於結果集可能非常大,會導致記憶體撐爆,因此對於大結果集的查詢,不建議採用這種方式。

3.2 sqlite3_prepare_v2
     prepare方式同樣支持查詢語句,主要分為3個階段,編譯,執行和結果集處理。前面更新SQL部分已經描述了prepare的基本步驟,這裡主要講結果集處理部分。首先通過sqlite3_column_count()可以得到結果集的列數目,通過sqlite3_column_type()可以得到具體某列的存儲類型,方便我們調用合適的sqlite3_column_xxx介面處理欄位值。主要有以下幾類:
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_double
sqlite3_column_text
sqlite3_column_blob

3.3 例子:遍歷結果集

int rc = sqlite3_prepare_v2(pDb, sql, -1, &pStmt, NULL);
//獲取列數目
int n_columns = sqlite3_column_count(pStmt);
do{
  ret = sqlite3_step(stmt);
  if (ret == SQLITE_ROW) 
  {
    //處理每一列
    for (i = 0; i < n_columns; i++)
    {
/*獲取列存儲類型*/       type
= sqlite3_column_type(stmt,i);       switch(type)       {         case SQLITE_INTEGER:          /*處理整型*/         sqlite3_column_int(stmt,i);
        break;         
case SQLITE_FLOAT:         /*處理浮點數*/         sqlite3_column_double(stmt,i);
        break;         
case SQLITE_TEXT:         /*處理字元串*/         sqlite3_column_text(stmt,i);
break;         
case SQLITE_BLOB:         /*處理二進位*/         sqlite3_column_blob(stmt, i));
        break;         
case SQLITE_NULL:         /*處理空*/       }     }   }   else if (ret == SQLITE_DONE) //結束   {     break;   } }while(true);

4.參數綁定
     SQLite通過prepare介面可以支持參數化的SQL語句,即帶問號的SQL語句。比如查詢語句select * from t where id=?,或者插入語句 insert into t(a,b,c) values(?,?,?)。通過參數化SQL,可以實現一次編譯多次執行的目的,由於問號是沒有意義的,因此需要調用sqlite3_bind_xxx介面來綁定具體的參數。主要有以下幾類:
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_double
sqlite3_bind_text
sqlite3_bind_blob
sqlite3_bind_null
關於綁定參數這裡提一點,對於sqlite3_bind_text和sqlite3_bind_blob介面,綁定參數占據的存儲空間是否可以被SQLite重用。介面中通過最後一個參數指定,參數值可以為SQLITE_STATIC和SQLITE_TRANSIENT。

SQLITE_STATIC:通知bind函數,參數使用空間是常量,不會改變,sqlite內部無需拷貝副本。
SQLITE_TRANSIENT:通知bind函數,參數使用空間可能會改變,sqlite內部需要有自己的副本。

4.1 例子:批量導入

//begin a transaction
if(sqlite3_exec(pdb, "begin", NULL, NULL, &errmsg) != SQLITE_OK)
{
  錯誤處理
  return ERROR;
}

sqlite3_prepare_v2(pdb, "insert into t1 values(?,?,?);", &stmt);
for (i = 0; i < n_rows; i++)
{
  for (j = 0; j < n_columns; j++)
  {
    switch(type)
    {
      case SQLITE_INTEGER:
      /*處理整型*/
      sqlite3_bind_int()
      break;       
case SQLITE_FLOAT:       /*處理浮點型*/       sqlite3_bind_double()
      break;       
case SQLITE_TEXT:       /*處理字元串類型*/       sqlite3_bind_text()
      break;
      case SQLITE_BLOB:       /*處理二進位類型*/       sqlite3_bind_blob
      break;       
case SQLITE_NULL:       sqlite3_bind_null(stmt, index);
      break;     }   }   sqlite3_step(stmt); //執行   sqlite3_reset(stmt);
//將已編譯的SQL語句恢復到初始狀態,保留語句相關的資源 } sqlite3_finalize(stmt); //結束語句,釋放語句句柄 if(sqlite3_exec(pdb, "commit", NULL, NULL, &errmsg) != SQLITE_OK) {   錯誤處理   return ERROR; }

小結
     本文詳細描述了SQLite中實現創建,修改,查詢資料庫的介面使用,包括單SQL語句,多SQL語句和參數化SQL。主要從四個場景展開描述,打開關閉資料庫連接,更新語句,查詢語句和參數化語句,並且對於每一種使用場景,給出了相應的代碼示範,希望能對大家熟悉使用SQLite有所幫助。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • android動態佈局相比靜態佈局,動態佈局不用再將xml轉變了佈局代碼,提高了一定的效率,當然可以忽略不記。動態佈局主要是比較靈活,可以很快的在代碼中直接修改佈局,並直接使用控制項進行業務邏輯開發。但代碼量通常比較大,維護沒有靜態佈局方便。不過,作為一個android開發人員,掌握一定的動態佈局.....
  • 一,效果圖。二,工程目錄。三,代碼。//點擊任何處,出現城市-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ UIActionSheet *city=[[UIActionSheet alloc] initWithT...
  • apache ab test使用轉載自:http://www.cnblogs.com/super-d2/p/3831155.html#tophttp://blog.chinaunix.net/uid-20382003-id-3032167.html先查看一下版本信息 ab -V(註意是大寫的V)2、...
  • 2016.1.11今天學了改變PS1的顏色,怎麼增加PS1變數找到文件(.bash_profile),或者bashrc export PS1="\[\e[32;1m\]Test $PWD> \[\e[0m\]" #顯示綠色,其中Test是額外增加要顯示的內容 export PS1="\[\e[35;...
  • 一、簡介 游戲目標:在地下城的最底層取得炎多的護符項鏈(Amulet of Yendor),並返回最上層,在聖祭壇上供奉給神靈。完成整個游戲的獎賞是,玩家會成為不朽的半神。 二、安裝 1)下載源碼 http://www.nethack.org/v360/downloads.html 2)編譯安裝 c...
  • Linux安裝tomcat。
  • 安裝svn需要依賴apr和apr-util這兩個軟體,所以先安裝這兩個軟體下載安裝APRwget http://apache.fayea.com//apr/apr-1.5.2.tar.gztar -zxvf apr-1.5.2.tar.gzcd apr-1.5.2./configure --pref...
  • Linux視頻教程集:序列之一:Linux基本操作和系統管理序列之二:Linux_C編程(IO+多線程+進程管理+進程通信+網路)序列之三:C++精講精煉(語法+STL+IO編程)序列之四:Qt編程式列之五:ARM嵌入式Linux開發(ARM硬體體系+指令集彙編+Linux開發) 鏈接序列1鏈接: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...