詳細介紹了使用SQLite3進行資料庫查詢的操作。
目錄
- 1. 概述
- 2. 詳論
- 2.1. 打開/關閉資料庫
- 2.2. 資料查詢
- 3. 參考
1. 概述
SQLite是一個嵌入式SQL資料庫引擎。與大多數其他 SQL 資料庫不同,SQLite 沒有單獨的伺服器程序。SQLite 直接讀寫普通磁盤檔案。具有多個表、索引、觸發器和視圖的完整SQL資料庫包含在單個磁盤檔案中。
SQLite比MySQL還要輕量級,官方提供的程式包大約1MB。但是這麼小的内容居然也是一個關系型資料庫,是以SQLite也很适合作為入門資料庫。其中,SQL最基礎的功能就是查詢了。
2. 詳論
2.1. 打開/關閉資料庫
使用資料庫的第一步當然是打開資料庫了。對于C接口來說,通常的實作是提供一個打開的接口,得到一個句柄或者指針,然後通過這個句柄或者指針進行進一步操作,包括關閉資料庫操作。SQLite正是這麼設計的:
int nRes = sqlite3_open("D:/test.db", &pDB);
if (nRes != SQLITE_OK) {
cout << "Open database fail: " << sqlite3_errmsg(pDB);
return 1;
}
sqlite3_close(pDB);
通過sqlite3_open()這個函數打開資料庫檔案,如果資料庫.db檔案不存在,則會建立這個檔案檔案。一旦建立成功,在程式結束時最好調用sqlite3_close()這個函數進行關閉,否則會記憶體洩漏。如果需要更加精細的打開資料庫檔案控制,最好使用sqlite3_open_v2()這個接口:
int flags =
SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE;
int nRes = sqlite3_open_v2("D:/test.db", &pDB, flags, nullptr);
sqlite3_open_v2()提供了很多打開資料庫檔案時的配置,例如如果需要在資料庫檔案不存在時進行建立,可以再加上SQLITE_OPEN_CREATE。
2.2. 資料查詢
如果在可視化管理工具(例如SQLite Expert)中,無論是查詢、插入、修改或者删除操作,都是直接輸入SQL語句,然後執行運作操作,就可以得到相應的結果。SQLite也有這樣的接口sqlite3_exec(),例如我們查詢一個表中所有的資料:
char* cErrMsg;
int res =
sqlite3_exec(pDB, "select * from metadata;", ResultCallBack, 0, &cErrMsg);
if (res != SQLITE_OK) {
cout << "select fail: " << cErrMsg << endl;
return false;
}
sqlite3_free(cErrMsg);
sqlite3_exec()是一個回調函數,每查詢到一行資料就調用一次:
int ResultCallBack(void* NotUsed, int argc, char** argv,
char** azColName) {
for (int i = 0; i < argc; i++) {
cout << azColName[i] << " = " << (argv[i] ? argv[i] : "NULL") << ", ";
}
cout << endl;
return 0;
}
如果需要進行更加細粒度的控制,那麼一個合适的做法是使用statement(語句)。首先,我們将我們需要的sql語句編譯成資料庫引擎識别的位元組碼,這個步驟可以叫做prepare(準備):
sqlite3_stmt* statement = nullptr;
int ret = sqlite3_prepare_v2(pDB, sqlStr, -1, &statement, nullptr);
if (ret != SQLITE_OK) {
printf("prepare error ret : %d\n", ret);
return 1;
}
接着,就是執行準備好的SQL語句:
while (sqlite3_step(statement) == SQLITE_ROW) {
//...
}
sqlite3_setp()每次查詢一行記錄,并且傳回SQLITE_ROW;知道查詢完成,就傳回SQLIET_DONE。通過這種方式實作了一種類似疊代器的操作,循環周遊每個查詢結果。
最後,我們對每一行查詢的結果進行解析:
while (sqlite3_step(statement) == SQLITE_ROW) {
cout << sqlite3_data_count(statement) << '\n';
cout << sqlite3_column_text(statement, 0) << '\t'
<< sqlite3_column_text(statement, 1) << '\n';
}
sqlite3_column_X是一系列函數,可以直接擷取每一行相應列的資料類型。例如擷取整型就是sqlite3_column_int。
另外,不要忘了關閉這個語句:
sqlite3_finalize(statement);
3. 參考
- SQLite3中核心C API