程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> SQLite3與C/C++的結合應用

SQLite3與C/C++的結合應用

編輯:C++入門知識

SQLite並沒有一次性做到位,只有下載這些東西是不能放在vs2010中並馬上使用的,下載下來的文件中有sqlite3.c/h/dll/def,還是不夠用的。我們需要的sqlite3.lib文件並不在其中,需要我們自己動手了。
這兒要用到visual studio提供的Visual Studio Command Prompt工具了。打開之後,進入含有sqlite3.dll和sqlite3.def的目錄下,輸入以下命令:
LIB /DEF:sqlite3.def /MACHINE:IX86 
就能生成sqlite3.exp和sqlite3.lib文件了,這樣在工程中就可以加入lib文件進行編譯了。

SEC 1:
因為只是演示API,所以這次在vs2010下建立一個空的win32工程SQLite3Test,在工程的屬性-鏈接-輸入中添加sqlite3.lib的引用。添加新的文件main.cpp,寫一個main函數,並編譯一下。
好,接下來把sqlite3.h/def/exp/lib通通放進SQLite3Test\SQLite3Test\目錄下,跟main.cpp在一起,如圖:

把sqlite3.dll跟生成的exe放在一起。
SEC 2:
接下來開始進行sqlite3的使用。引入sqlite3.h頭文件,並寫下如下代碼:
#include <iostream>
#include "sqlite3.h"
 
using namespace std;
 
int main(int argc, char** argv)
{
    sqlite3 * conn = NULL;
    char * err_msg = NULL;
    char sql[200] = "";
 
    // 打開數據庫, 創建連接
    if(sqlite3_open("test.db", &conn) != SQLITE_OK)
    {
        printf("無法打開!");
    }
 
    // 關閉連接。
    if (sqlite3_close(conn) != SQLITE_OK)
    {
        printf("無法關閉,錯誤代碼: %s\n", sqlite3_errmsg(conn));
        exit(-1);
    }
 
    printf("操作成功!\n");
 
    return 0;
}
sqlite3_open的函數原型如下:
SQLITE_API int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
作用就不言而喻了,打開數據庫。
第一個參數是數據庫文件的名稱,如果沒有,那就會自動創建一個。
第二個參數是sqlite3的實例句柄的指針的指針。。(看到這兒我想起來,當時在linux下自己寫mysql的C++api的時候,也是用的雙重指針,搞死個人喲。。)
常言道:“有打開,就有關閉!”,所以sqlite3_close()就起了這個作用。
不過sqlite3_close的原型是這樣的:
SQLITE_API int sqlite3_close(sqlite3 *); //要格外注意雙重指針和普通指針。。
有了上面的萬金油例子,想必已經對初始化有所了解了。運行後就在Debug目錄下多了個test.db文件,不過大小為0KB,因為木有內容嘛!
SEC 3:
在數據庫中創建表並插入數據。在open和close的之間寫入如下代碼:
// 執行SQL 
sprintf(sql, "CREATE TABLE test_for_cpp \
    (id int, name varchar(20), age int)"); 
if (sqlite3_exec(conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) 

    printf("操作失敗,錯誤代碼: %s", err_msg); 
    exit(-1); 

 
//添加10條記錄
for (int i = 0; i < 10; i++)
{
    // 執行SQL
    sprintf(sql, "INSERT INTO test_for_cpp \
        (id, name, age) VALUES \
        (%d, '%s', %d)", i, "testPeople", i);
    if (sqlite3_exec(conn, sql, NULL, NULL, &err_msg) != SQLITE_OK) 
{     
printf("操作失敗,錯誤代碼: %s", err_msg);     
exit(-1); 

}
sqlite3_exec的原型如下:
SQLITE_API 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 */
);
第一個參數為sqlite3實例。
第二個參數為要執行的sql語句。
第三個參數為回調函數的指針。因為這裡只是創建表和插入數據,並沒有數據返回,所以不需要填寫回調函數。以NULL代替。
第四個參數為回調函數所要使用的參數。同第三條。
第五個參數為錯誤信息。
這次再運行一下,就可以看到test.db已經不再是0KB了。

SEC 4:
再常言道:“有插入,就有讀取!”下面來讀取數據庫文件中的數據。
剛才提到了sqlite3_exec的回調函數,現在需要這個函數了。首先聲明一個回調函數:
int sqlite3_exec_callback(void *data, int nColumn, 
                          char **colValues, char **colNames);
四個參數的類型不能變。
然後寫下該回調函數的實現:
int sqlite3_exec_callback(void *data, int nColumn, char **colValues, char **colNames)
{
    for (int i = 0; i < nColumn; i++)
    {
        printf("%s\t", colValues[i]);
    }
    printf("\n");
 
    return 0;
}
接下來在插入條目語句的後面寫下下面的語句:
// 查詢
sprintf(sql, "SELECT * FROM test_for_cpp");
sqlite3_exec(conn, sql, &sqlite3_exec_callback, 0, &err_msg);
TIP: 前面創建表、插入數據的代碼可以先注釋掉,否則運行一次就會插入10條數據,會造成點困擾。
運行就可以看到結果了:

因為該回調函數每從數據庫中取出一條數據就要調用一次,所以這是最耗時間的過程,這塊代碼應該盡量高效。
這只是一個簡單的例子,不過已經足夠平時的小眾軟件使用了。一些高級的用法比如sqlite3_db_mutex(讀寫互斥鎖)、sqlite3_backup_step(差異備份)等等,就可以看看sqlite3官方的教程了(猛戳傳送)。
作者:satanness

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved