SQLite是一款輕型的本地檔案資料庫,是遵守ACID的關聯式資料庫管理系統。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它的功能強、速度快,它佔用資源非常的低,在嵌入式裝置中,可能只需要幾百K的記憶體就夠了。它能夠支援Windows/Linux/Unix等主流的作業系統,同時能夠跟很多程式語言相結合。
一、SQLite的資料類型
在進行資料庫操作之前,有個問題需要說明,就是SQLite的資料類型,和其他的資料庫不同,Sqlite支援的資料類型有他自己的特色:Typelessness(無類型)。 SQLite是無類型的,這意味著你可以儲存任何類型的資料到你所想要儲存的任何錶的任何列中, 無論這列聲明的資料類型是什麼。
而大多數的資料庫在資料類型上都有嚴格的限制,在建立表的時候,每一列都必須制定一個資料類型,只有符合該資料類型的資料可以被儲存在這一列當中。而在SQLite 2.X中,資料類型這個屬性只屬於資料本生,而不和資料被存在哪一列有關,也就是說資料的類型並不受資料列限制(有一個例外:INTEGER PRIMARY KEY,該列只能存整型資料)。
但是當SQLite進入到3.0版本的時候,這個問題似乎又有了新的答案,SQLite的開發人員開始限制這種無類型的使用,在3.0版本當中,每一列開始擁有自己的類型,並且在資料存入該列的時候,資料庫會試圖把資料的類型向該類型轉換,然後以轉換之後的類型儲存。當然,如果轉換被認為是不可行的,SQLite仍然會儲存這個資料,就像他的前任版本一樣。
舉個例子,如果你企圖向一個INTEGER類型的列中插入一個字串,SQLite會檢查這個字串是否有整型資料的特徵, 如果有而且可以被資料庫所識別,那麼該字串會被轉換成整型再儲存,如果不行,則還是作為字串儲存。
誠然SQLite允許忽略資料類型, 但是仍然建議在你的Create Table語句中指定資料類型. 因為資料類型對於你和其他的程式員交流, 或者你準備換掉你的資料庫引擎時能起到一個提示或協助的作用. SQLite支援常見的資料類型, 如:
1.NULL,值是NULL
2.INTEGER,值是有符號整形,根據值的大小以1,2,3,4,6或8位元組存放
3.REAL,值是浮點型值,以8位元組IEEE浮點數存放
4.TEXT,值是文本字串,使用資料庫編碼(UTF-8,UTF-16BE或者UTF-16LE)
5.BLOB,只是一個資料區塊,完全按照輸入存放(即沒有準換)
SQLite的操作介面
SQLite的2個重要結構體:
sqlite3 *pdb,資料庫控制代碼,跟檔案控制代碼FILE很類似
sqlite3_stmt *stmt,這個相當於ODBC的Command對象,用於儲存編譯好的SQL語句
SQLite的5個主要的函數:
sqlite3_open(), 開啟資料庫
sqlite3_exec(),執行非查詢的sql語句
sqlite3_prepare(),準備sql語句,執行select語句或者要使用parameter bind時,用這個函數(封裝了sqlite3_exec).
sqlite3_step(),在調用sqlite3_prepare後,使用這個函數在記錄集中移動。
sqlite3_close(),關閉資料庫檔案
還有一系列的函數,用於從屬記錄集欄位中擷取資料,如:
sqlite3_column_text(),取text類型的資料
sqlite3_column_blob(),取blob類型的資料
sqlite3_column_int(),取int類型的資料
C++使用前準備
下載SQLite,分別從http://www.sqlite.org/2013/sqlite-amalgamation-3071700.zip、 http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071700.zip下載SQLite的源檔案和庫檔案。
但是sqlite-dll-win32-x86-3071700.zip中並沒有提供SQLite的lib檔案,需要自己編譯產生。解壓sqlite-dll-win32-x86-3071700.zip到sqlite-dll-win32-x86-3071700目錄,再將VS安裝目錄下VC中的LIB.EXE、LINK.EXE、mspdb80.dll(這裡用的是VS2008)拷貝到sqlite-dll-win32-x86-3071700,執行LIB.EXE /DEF:SQLITE3.DEF /MACHINE:IX86 就可以得到SQLITE3.LIB檔案。
C++訪問SQLite
C++對SQLite進行操作的代碼如下:
複製代碼 代碼如下:
#include "stdafx.h"
#include <string.h>
using namespace std;
#include "sqlite3.h"
#pragma comment(lib, "SQLITE3.LIB")
static int SelectCallback(void *notUsed, int argc, char **argv, char **azColName)
{
for (int i = 0 ; i < argc ; i++)
{
printf("%s = %s", azColName[i], (argv[i] ? argv[i] : "NULL"));
if (i != argc -1)
{
printf(", ");
}
}
printf("\n");
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
sqlite3 * pDB;
char* errMsg;
// 開啟SQLite資料庫
int res = sqlite3_open("sql.db", &pDB);
if ( res != SQLITE_OK ){
printf("Can't open database: %s\n", sqlite3_errmsg(pDB));
sqlite3_close(pDB);
return -1;
}
// 建立表
string strSQL= "create table test (id int, name text);";
res = sqlite3_exec(pDB , strSQL.c_str() ,0 ,0, &errMsg);
if (res != SQLITE_OK)
{
printf("Create table error: %s\n", errMsg);
//return -1;
}
// 插入資料
res = sqlite3_exec(pDB,"begin transaction;",0,0, &errMsg);
for (int i= 1; i < 10; ++i)
{
char sql[512];
sprintf_s(sql, "insert into test values(%d, %s);", (i+10), "\"Test Name\"");
res = sqlite3_exec(pDB, sql,0,0, &errMsg);
if (res != SQLITE_OK)
{
printf("Insert error: %s\n", errMsg);
return -1;
}
}
res = sqlite3_exec(pDB,"commit transaction;",0,0, &errMsg);
// 查詢資料
strSQL= "select * from test;";
res = sqlite3_exec(pDB, strSQL.c_str(), SelectCallback, 0 , &errMsg);
if (res != SQLITE_OK)
{
printf("Select error: %s\n", errMsg);
return -1;
}
// 關閉資料庫
sqlite3_close(pDB);
return 0;
}