C/C++通過(guò)SQLite SDK實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查操作
SQLite,作為一款嵌入式關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),一直以其輕量級(jí)、零配置以及跨平臺(tái)等特性而備受青睞。不同于傳統(tǒng)的數(shù)據(jù)庫(kù)系統(tǒng),SQLite是一個(gè)庫(kù),直接與應(yīng)用程序一同編譯和鏈接,無(wú)需單獨(dú)的數(shù)據(jù)庫(kù)服務(wù)器進(jìn)程,實(shí)現(xiàn)了數(shù)據(jù)庫(kù)的零配置管理。這種設(shè)計(jì)理念使得SQLite成為許多嵌入式系統(tǒng)、移動(dòng)應(yīng)用和小型項(xiàng)目中的首選數(shù)據(jù)庫(kù)引擎。
SQLite的特點(diǎn)包括:
- 嵌入式數(shù)據(jù)庫(kù)引擎: SQLite 是一個(gè)嵌入式數(shù)據(jù)庫(kù)引擎,意味著它是一個(gè)庫(kù),與應(yīng)用程序一同編譯和鏈接,而不是作為獨(dú)立的進(jìn)程運(yùn)行。
- 零配置: 無(wú)需配置或管理。SQLite 不需要一個(gè)獨(dú)立的數(shù)據(jù)庫(kù)服務(wù)器進(jìn)程,所有的操作都是直接在存儲(chǔ)在文件中的數(shù)據(jù)庫(kù)上執(zhí)行。
- 輕量級(jí): SQLite 是一個(gè)輕量級(jí)的數(shù)據(jù)庫(kù),相對(duì)于一些其他數(shù)據(jù)庫(kù)管理系統(tǒng)來(lái)說(shuō),它的內(nèi)存占用和資源消耗相對(duì)較小。
- 支持 SQL: SQLite 支持大部分標(biāo)準(zhǔn)的 SQL 語(yǔ)法,并提供了事務(wù)支持,包括隔離級(jí)別和回滾。
- 跨平臺(tái): SQLite 可以在各種操作系統(tǒng)上運(yùn)行,包括 Windows、Linux、macOS 和其他嵌入式系統(tǒng)。
- 自給自足: SQLite 數(shù)據(jù)庫(kù)是一個(gè)單一的磁盤文件,整個(gè)數(shù)據(jù)庫(kù)被存儲(chǔ)在一個(gè)文件中,這使得備份、復(fù)制或傳輸數(shù)據(jù)庫(kù)變得非常容易。
- 開(kāi)源: SQLite 是一個(gè)開(kāi)源項(xiàng)目,采用公共領(lǐng)域授權(quán)(Public Domain License),可以在商業(yè)和非商業(yè)項(xiàng)目中免費(fèi)使用。
SQLite 數(shù)據(jù)庫(kù)以其獨(dú)特的自給自足特性脫穎而出,整個(gè)數(shù)據(jù)庫(kù)被存儲(chǔ)在一個(gè)單一的磁盤文件中,使得備份、復(fù)制或傳輸數(shù)據(jù)庫(kù)變得異常簡(jiǎn)單。而作為一款開(kāi)源項(xiàng)目,SQLite采用了公共領(lǐng)域授權(quán),可以在商業(yè)和非商業(yè)項(xiàng)目中免費(fèi)使用。
由于該數(shù)據(jù)庫(kù)的小巧和簡(jiǎn)潔所以在使用上也非常容易,當(dāng)讀者下載好附件以后會(huì)看到如下圖所示的文件;
使用時(shí)只需要將sqlite3.h
與sqlite3.c
文件導(dǎo)入到項(xiàng)目中并使用#include "sqlite3.h"
即可,無(wú)需做其他配置,圖中的sqlite3.dll
是動(dòng)態(tài)庫(kù),sqlite3.exe
則是一個(gè)命令行版本的數(shù)據(jù)庫(kù)可在測(cè)試時(shí)使用它。
打開(kāi)與關(guān)閉庫(kù)
sqlite3_open
用于打開(kāi)或創(chuàng)建一個(gè) SQLite 數(shù)據(jù)庫(kù)文件。該函數(shù)的原型如下:
int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ );
filename
: 要打開(kāi)或創(chuàng)建的 SQLite 數(shù)據(jù)庫(kù)文件的路徑。如果文件不存在,將會(huì)創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)文件。ppDb
: 用于存儲(chǔ) SQLite 數(shù)據(jù)庫(kù)句柄(handle)的指針。SQLite 數(shù)據(jù)庫(kù)句柄是與一個(gè)打開(kāi)的數(shù)據(jù)庫(kù)關(guān)聯(lián)的結(jié)構(gòu),它在后續(xù)的 SQLite 操作中用作標(biāo)識(shí)。
該函數(shù)返回一個(gè)整數(shù)值,代表函數(shù)的執(zhí)行狀態(tài)。如果函數(shù)成功執(zhí)行,返回 SQLITE_OK
。如果有錯(cuò)誤發(fā)生,返回一個(gè)表示錯(cuò)誤代碼的整數(shù)值??梢酝ㄟ^(guò) sqlite3_errmsg
函數(shù)獲取更詳細(xì)的錯(cuò)誤信息。
sqlite3_close
用于關(guān)閉數(shù)據(jù)庫(kù)連接的函數(shù)。其原型如下:
int sqlite3_close(sqlite3*);
sqlite3
: 要關(guān)閉的 SQLite 數(shù)據(jù)庫(kù)連接的句柄。
該函數(shù)返回一個(gè)整數(shù)值,用于表示函數(shù)的執(zhí)行狀態(tài)。如果函數(shù)成功執(zhí)行,返回 SQLITE_OK
。如果有錯(cuò)誤發(fā)生,返回一個(gè)表示錯(cuò)誤代碼的整數(shù)值。
使用 sqlite3_close
函數(shù)可以釋放與數(shù)據(jù)庫(kù)連接相關(guān)的資源,并確保數(shù)據(jù)庫(kù)文件被正確關(guān)閉。在關(guān)閉數(shù)據(jù)庫(kù)連接之前,應(yīng)該確保已經(jīng)完成了所有需要執(zhí)行的 SQL 語(yǔ)句,并在需要的情況下檢查執(zhí)行結(jié)果。
// 打開(kāi)數(shù)據(jù)庫(kù)并返回句柄 sqlite3* open_database(std::string database_name) { int ref =-1; sqlite3 *db = 0; ref = sqlite3_open(database_name.c_str(), &db); if (ref == SQLITE_OK) return db; return false; } // 關(guān)閉數(shù)據(jù)庫(kù) bool close_database(sqlite3 *db) { int ref = sqlite3_close(db); if (ref == SQLITE_OK) return true; return false; }
執(zhí)行查詢語(yǔ)句
sqlite3_exec
用于執(zhí)行 SQL 語(yǔ)句的高級(jí)接口函數(shù)。它的原型如下:
int sqlite3_exec( sqlite3* db, /* Database handle */ const char* sql, /* SQL statement, UTF-8 encoded */ int (*callback)( /* Callback function */ void*, /* Callback parameter */ int, /* Number of columns in the result set */ char**, /* Array of column values */ char** /* Array of column names */ ), void* callback_param, /* 1st argument to callback function */ char** errmsg /* Error msg written here */ );
db
: SQLite 數(shù)據(jù)庫(kù)連接的句柄。sql
: 要執(zhí)行的 SQL 語(yǔ)句,以 UTF-8 編碼。callback
: 回調(diào)函數(shù),用于處理查詢結(jié)果的每一行數(shù)據(jù)。callback_param
: 傳遞給回調(diào)函數(shù)的參數(shù)。errmsg
: 用于存儲(chǔ)錯(cuò)誤消息的指針。
sqlite3_exec
函數(shù)執(zhí)行一個(gè)或多個(gè) SQL 語(yǔ)句,并對(duì)每一條語(yǔ)句的執(zhí)行結(jié)果調(diào)用指定的回調(diào)函數(shù)。回調(diào)函數(shù)的原型如下:
int callback( void* callback_param, /* 參數(shù),由 sqlite3_exec 傳遞給回調(diào)函數(shù) */ int num_columns, /* 結(jié)果集中的列數(shù) */ char** column_values, /* 指向結(jié)果集中當(dāng)前行的列值的數(shù)組 */ char** column_names /* 指向結(jié)果集中列名的數(shù)組 */ );
callback_param
: 回調(diào)函數(shù)的參數(shù),由sqlite3_exec
傳遞給回調(diào)函數(shù)。num_columns
: 結(jié)果集中的列數(shù)。column_values
: 指向結(jié)果集中當(dāng)前行的列值的數(shù)組。column_names
: 指向結(jié)果集中列名的數(shù)組。
回調(diào)函數(shù)返回一個(gè)整數(shù),用于指示是否繼續(xù)執(zhí)行后續(xù)的 SQL 語(yǔ)句。如果回調(diào)函數(shù)返回非零值,sqlite3_exec
將停止執(zhí)行 SQL,并立即返回。
sqlite3_prepare_v2
用于準(zhǔn)備 SQL 語(yǔ)句的接口函數(shù)。它的原型如下:
int sqlite3_prepare_v2( sqlite3* db, /* Database handle */ const char* sql, /* SQL statement, UTF-8 encoded */ int sql_len, /* Length of SQL statement in bytes, or -1 for zero-terminated */ sqlite3_stmt** stmt, /* OUT: Statement handle */ const char** tail /* OUT: Pointer to unused portion of SQL statement */ );
db
: SQLite 數(shù)據(jù)庫(kù)連接的句柄。sql
: 要準(zhǔn)備的 SQL 語(yǔ)句,以 UTF-8 編碼。sql_len
: SQL 語(yǔ)句的長(zhǎng)度,如果為 -1,則表示 SQL 語(yǔ)句以 null 結(jié)尾。stmt
: 用于存儲(chǔ)準(zhǔn)備好的語(yǔ)句句柄的指針。tail
: 用于存儲(chǔ)未使用的 SQL 語(yǔ)句的指針。
sqlite3_prepare_v2
函數(shù)用于將 SQL 語(yǔ)句編譯成一個(gè) SQLite 語(yǔ)句對(duì)象(prepared statement)。這個(gè)對(duì)象可以被多次執(zhí)行,每次執(zhí)行時(shí)可以綁定不同的參數(shù)。stmt
參數(shù)將用于存儲(chǔ)編譯后的語(yǔ)句的句柄,以供后續(xù)的操作。
sqlite3_step
執(zhí)行預(yù)編譯 SQL 語(yǔ)句的接口函數(shù)。它的原型如下:
int sqlite3_step(sqlite3_stmt*);
sqlite3_stmt*
: 由 sqlite3_prepare_v2
預(yù)編譯的 SQL 語(yǔ)句的句柄。
sqlite3_step
函數(shù)用于執(zhí)行由 sqlite3_prepare_v2
預(yù)編譯的 SQL 語(yǔ)句。在執(zhí)行過(guò)程中,可以通過(guò)不斷調(diào)用 sqlite3_step
來(lái)逐行獲取查詢結(jié)果,直到結(jié)果集結(jié)束。對(duì)于非查詢語(yǔ)句(如 INSERT
、UPDATE
、DELETE
),sqlite3_step
函數(shù)執(zhí)行一次即可完成操作。
該函數(shù)的返回值表示執(zhí)行的結(jié)果,可能的返回值包括:
SQLITE_ROW
: 成功獲取一行數(shù)據(jù)。SQLITE_DONE
: 執(zhí)行完成,沒(méi)有更多的數(shù)據(jù)可用(用于非查詢語(yǔ)句)。- 其他錯(cuò)誤碼,表示執(zhí)行過(guò)程中出現(xiàn)了錯(cuò)誤。
sqlite3_column_text
用于獲取查詢結(jié)果集中某一列的文本值。其原型為:
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
sqlite3_stmt*
: 由sqlite3_prepare_v2
預(yù)編譯的 SQL 語(yǔ)句的句柄。int iCol
: 列的索引,從0開(kāi)始。
該函數(shù)返回指向字符串值的指針,該字符串值是查詢結(jié)果集中指定列的文本表示。需要注意的是,返回的指針指向 SQLite 內(nèi)部的存儲(chǔ)區(qū),應(yīng)該在使用完之后盡早釋放資源。
sqlite3_column_int
用于獲取查詢結(jié)果集中某一列的整數(shù)值。其原型為:
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_stmt*
: 由sqlite3_prepare_v2
預(yù)編譯的 SQL 語(yǔ)句的句柄。int iCol
: 列的索引,從0開(kāi)始。
該函數(shù)返回查詢結(jié)果集中指定列的整數(shù)表示。需要注意的是,如果該列不是整數(shù)類型,或者包含的數(shù)據(jù)無(wú)法轉(zhuǎn)換為整數(shù),那么返回的結(jié)果可能不是有效的整數(shù)值。
sqlite3_finalize
用于釋放一個(gè)預(yù)備語(yǔ)句對(duì)象(prepared statement)。在使用 sqlite3_prepare_v2
函數(shù)準(zhǔn)備 SQL 語(yǔ)句后,需要使用 sqlite3_finalize
來(lái)釋放相應(yīng)的語(yǔ)句對(duì)象。
該函數(shù)的原型為:
int sqlite3_finalize(sqlite3_stmt *pStmt);
sqlite3_stmt *pStmt
: 指向要釋放的語(yǔ)句對(duì)象的指針。
該函數(shù)返回 SQLITE_OK
表示成功,返回其他錯(cuò)誤碼表示失敗。
// 執(zhí)行SQL語(yǔ)句 bool exec_sql(sqlite3 *db, char *sql) { char *error_code = 0; int ref = sqlite3_exec(db, sql, 0, 0, &error_code); if (ref == SQLITE_OK) { return true; } return false; } // 插入數(shù)據(jù) bool insert_data(sqlite3 *db, char *sql) { sqlite3_stmt *stmt = 0; // 插入前檢查語(yǔ)句合法性, -1自動(dòng)計(jì)算SQL長(zhǎng)度 int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0); if (ref == SQLITE_OK) { sqlite3_step(stmt); // 執(zhí)行語(yǔ)句 sqlite3_finalize(stmt); // 清理語(yǔ)句句柄 return true; } sqlite3_finalize(stmt); return false; } // 查詢數(shù)據(jù)集 bool select_data(sqlite3 *db, char *sql) { sqlite3_stmt *stmt = 0; int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0); if (ref == SQLITE_OK) { // 每調(diào)一次sqlite3_step()函數(shù),stmt就會(huì)指向下一條記錄 while (sqlite3_step(stmt) == SQLITE_ROW) { // 取出第1列字段的值 const unsigned char *name = sqlite3_column_text(stmt, 1); // 取出第2列字段的值 int age = sqlite3_column_int(stmt, 2); std::cout << "姓名: " << name << " 年齡: " << age << std::endl; } } else { sqlite3_finalize(stmt); return false; } sqlite3_finalize(stmt); return true; }
調(diào)用查詢語(yǔ)句
創(chuàng)建數(shù)據(jù)庫(kù)
首先打開(kāi)了名為 "database.db"
的 SQLite 數(shù)據(jù)庫(kù),并創(chuàng)建了一個(gè)名為 "LySharkDB"
的表,該表格包含了id、name、age
和 msg
四個(gè)字段。隨后,通過(guò)執(zhí)行 SQL 語(yǔ)句創(chuàng)建了這個(gè)表格。最后,關(guān)閉了數(shù)據(jù)庫(kù)連接。這段代碼主要用于數(shù)據(jù)庫(kù)初始化操作,確保了數(shù)據(jù)庫(kù)中包含了指定的表格結(jié)構(gòu)。
int main(int argc, char *argv[]) { sqlite3* open_db = open_database("database.db"); if (open_db != false) { bool create_table_ref; std::string sql = "create table LySharkDB(" "id int auto_increment primary key," "name char(30) not null," "age int not null," "msg text default null" ")"; // 運(yùn)行創(chuàng)建表操作 char run_sql[1024] = { 0 }; strcpy(run_sql, sql.c_str()); create_table_ref = exec_sql(open_db, run_sql); } close_database(open_db); std::system("pause"); return 0; }
上述代碼運(yùn)行后則可以創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)database.db
表名為LySharkDB
讀者可以使用數(shù)據(jù)庫(kù)工具打開(kāi)該表,其結(jié)構(gòu)如下所示;
插入數(shù)據(jù)測(cè)試
創(chuàng)建數(shù)據(jù)庫(kù)后,接著就是插入數(shù)據(jù)測(cè)試,插入時(shí)可以使用insert_data
,如下代碼項(xiàng)數(shù)據(jù)庫(kù)中插入5條記錄;
int main(int argc, char *argv[]) { sqlite3* open_db = open_database("./database.db"); if (open_db != false) { bool create_table_ref; // 運(yùn)行插入記錄 if (create_table_ref == true) { bool insert_ref = 0; insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(1,'lyshark',1,'hello lyshark');"); insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(2,'guest',2,'hello guest');"); insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(3,'admin',3,'hello admin');"); insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(4,'wang',4,'hello wang');"); insert_ref = insert_data(open_db, "insert into LySharkDB(id,name,age,msg) values(5,'sqlite',5,'hello sql');"); if (insert_ref == true) { std::cout << "插入完成" << std::endl; } } } close_database(open_db); std::system("pause"); return 0; }
插入后,打開(kāi)數(shù)據(jù)庫(kù)管理軟件,可看到插入后的記錄;
查詢與刪除數(shù)據(jù)
而查詢刪除與增加記錄,我們這里直接使用exec_sql()
函數(shù),通過(guò)傳入不同的SQL語(yǔ)句實(shí)現(xiàn)。
int main(int argc, char *argv[]) { sqlite3* open_db = open_database("./database.db"); if (open_db != false) { // 刪除記錄 bool delete_ref = exec_sql(open_db, "delete from LySharkDB where id = 5;"); if (delete_ref == true) { std::cout << "刪除完成." << std::endl; } // 更新記錄 bool update_ref = exec_sql(open_db, "update LySharkDB set name='lyshark' where id = 4;"); if (update_ref == true) { std::cout << "更新完成." << std::endl; } // 查詢數(shù)據(jù) bool select_ref = select_data(open_db, "select * from LySharkDB;"); if (select_ref == true) { std::cout << "查詢完畢." << std::endl; } } close_database(open_db); std::system("pause"); return 0; }
執(zhí)行更新后的表記錄如下所示;
查詢區(qū)間數(shù)據(jù)
首先創(chuàng)建一些數(shù)據(jù)集,這里通過(guò)循環(huán)生成并插入數(shù)據(jù),如下代碼中新建一個(gè)TimeDB
數(shù)據(jù)表,其中有三個(gè)字段uid,host_time,cpu_value
;
#include <iostream> #include <string> #include <map> #include <vector> #include <time.h> #include "sqlite3.h" #include <boost/lexical_cast.hpp> #include <boost/format.hpp> using namespace std; using namespace boost; // 獲取本地時(shí)間日期 std::string get_local_datetime() { char ct[80]; time_t tt; struct tm *tblock; tt = time(NULL); tblock = localtime(&tt); strftime(ct, sizeof(ct), "%Y-%m-%d %H:%M:%S", tblock); return ct; } // 初始化創(chuàng)建表結(jié)構(gòu) void Init_Database() { sqlite3* open_db = open_database("./database.db"); if (open_db != false) { bool create_table_ref; std::string sql = "create table TimeDB(" "uid primary key," "host_time char(128) not null," "cpu_value int not null" ");"; char run_sql[1024] = { 0 }; strcpy(run_sql, sql.c_str()); exec_sql(open_db, run_sql); } close_database(open_db); } // 批量生成時(shí)間字符串并插入數(shù)據(jù)表 void Insert_Test() { sqlite3* open_db = open_database("./database.db"); for (int x = 0; x < 1000; x++) { // 獲取本地日期時(shí)間 std::string local_times = get_local_datetime(); std::string format_string = boost::str(boost::format("insert into TimeDB(uid,host_time,cpu_value) values(%d,'%s',%d);") % x %local_times %x); std::cout << "執(zhí)行SQL: " << format_string << std::endl; char run_sql[1024] = { 0 }; strcpy(run_sql, format_string.c_str()); insert_data(open_db, run_sql); _sleep(1000); } close_database(open_db); } int main(int argc, char *argv[]) { sqlite3* open_db = open_database("./database.db"); Init_Database(); Insert_Test(); std::system("pause"); return 0; }
如下是五分鐘的模擬數(shù)據(jù);
當(dāng)有了數(shù)據(jù)則再查詢,代碼中Select_Time_List
函數(shù)演示了如何通過(guò)時(shí)間查詢一個(gè)區(qū)間的數(shù)據(jù),并返回一個(gè)容器列表給被調(diào)用者使用,查詢代碼如下所示;
#include <iostream> #include <string> #include <map> #include <vector> #include <time.h> #include "sqlite3.h" #include <boost/lexical_cast.hpp> #include <boost/format.hpp> using namespace std; using namespace boost; // 打開(kāi)數(shù)據(jù)庫(kù)并返回句柄 sqlite3* open_database(std::string database_name) { int ref = -1; sqlite3 *db = 0; ref = sqlite3_open(database_name.c_str(), &db); if (ref == SQLITE_OK) return db; return false; } // 關(guān)閉數(shù)據(jù)庫(kù) bool close_database(sqlite3 *db) { int ref = sqlite3_close(db); if (ref == SQLITE_OK) return true; return false; } // 執(zhí)行SQL語(yǔ)句 bool exec_sql(sqlite3 *db, char *sql) { char *error_code = 0; int ref = sqlite3_exec(db, sql, 0, 0, &error_code); if (ref == SQLITE_OK) { return true; } return false; } // 插入數(shù)據(jù) bool insert_data(sqlite3 *db, char *sql) { sqlite3_stmt *stmt = 0; // 插入前檢查語(yǔ)句合法性, -1自動(dòng)計(jì)算SQL長(zhǎng)度 int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0); if (ref == SQLITE_OK) { sqlite3_step(stmt); // 執(zhí)行語(yǔ)句 sqlite3_finalize(stmt); // 清理語(yǔ)句句柄 return true; } sqlite3_finalize(stmt); return false; } // 查詢數(shù)據(jù)集 bool select_data(sqlite3 *db, char *sql) { sqlite3_stmt *stmt = 0; int ref = sqlite3_prepare_v2(db, sql, -1, &stmt, 0); if (ref == SQLITE_OK) { // 每調(diào)一次sqlite3_step()函數(shù),stmt就會(huì)指向下一條記錄 while (sqlite3_step(stmt) == SQLITE_ROW) { // 取出第1列字段的值 const unsigned char *name = sqlite3_column_text(stmt, 1); // 取出第2列字段的值 int age = sqlite3_column_int(stmt, 2); std::cout << "姓名: " << name << " 年齡: " << age << std::endl; } } else { sqlite3_finalize(stmt); return false; } sqlite3_finalize(stmt); return true; } // 獲取本地時(shí)間日期 std::string get_local_datetime() { char ct[80]; time_t tt; struct tm *tblock; tt = time(NULL); tblock = localtime(&tt); strftime(ct, sizeof(ct), "%Y-%m-%d %H:%M:%S", tblock); return ct; } // 初始化創(chuàng)建表結(jié)構(gòu) void Init_Database() { sqlite3* open_db = open_database("./database.db"); if (open_db != false) { bool create_table_ref; std::string sql = "create table TimeDB(" "uid primary key," "host_time char(128) not null," "cpu_value int not null" ");"; char run_sql[1024] = { 0 }; strcpy(run_sql, sql.c_str()); exec_sql(open_db, run_sql); } close_database(open_db); } // 批量生成時(shí)間字符串并插入數(shù)據(jù)表 void Insert_Test() { sqlite3* open_db = open_database("./database.db"); for (int x = 0; x < 1000; x++) { // 獲取本地日期時(shí)間 std::string local_times = get_local_datetime(); std::string format_string = boost::str(boost::format("insert into TimeDB(uid,host_time,cpu_value) values(%d,'%s',%d);") % x %local_times %x); std::cout << "執(zhí)行SQL: " << format_string << std::endl; char run_sql[1024] = { 0 }; strcpy(run_sql, format_string.c_str()); insert_data(open_db, run_sql); _sleep(1000); } close_database(open_db); } // 查詢時(shí)間區(qū)間并返回 傳入開(kāi)始時(shí)間與結(jié)束時(shí)間,過(guò)濾出特定的記錄 bool Select_Time_List(sqlite3 *db, std::vector<std::map<std::string, int>> &time_ref, std::string start_time, std::string end_time) { sqlite3_stmt *stmt = 0; std::string format_string = boost::str(boost::format("select * from TimeDB where host_time >= '%s' and host_time <= '%s';") % start_time %end_time); char run_sql[1024] = { 0 }; strcpy(run_sql, format_string.c_str()); int ref = sqlite3_prepare_v2(db, run_sql, -1, &stmt, 0); if (ref == SQLITE_OK) { while (sqlite3_step(stmt) == SQLITE_ROW) { std::map < std::string, int > ptr; // 取出第一個(gè)和第二個(gè)字段 const unsigned char *time_text = sqlite3_column_text(stmt, 1); const int cpu_value = sqlite3_column_int(stmt, 2); // 放入一個(gè)map容器中 ptr[boost::lexical_cast<std::string>(time_text)] = cpu_value; time_ref.push_back(ptr); } sqlite3_finalize(stmt); return true; } sqlite3_finalize(stmt); return false; } int main(int argc, char *argv[]) { sqlite3* open_db = open_database("./database.db"); //Init_Database(); //Insert_Test(); // 查詢 2023-11-25 19:52:31 - 2023-11-25 19:53:35 區(qū)間內(nèi)的所有的負(fù)載情況 std::vector<std::map<std::string, int>> db_time; bool is_true = Select_Time_List(open_db, db_time, "2023-11-25 19:52:31", "2023-11-25 19:53:35"); if (is_true == true) { for (int x = 0; x < db_time.size(); x++) { // 輸出該區(qū)間內(nèi)的數(shù)據(jù) std::map < std::string, int>::iterator ptr; for (ptr = db_time[x].begin(); ptr != db_time[x].end(); ptr++) { std::cout << "時(shí)間區(qū)間: " << ptr->first << " CPU利用率: " << ptr->second << std::endl; } } } std::system("pause"); return 0; }
例如代碼中我們查詢2023-11-25 19:52:31 - 2023-11-25 19:53:35
這個(gè)區(qū)間內(nèi)的數(shù)據(jù)信息,并返回一個(gè)map
容器給被調(diào)用者,運(yùn)行效果如下所示;
以上就是C/C++通過(guò)SQLite SDK實(shí)現(xiàn)數(shù)據(jù)庫(kù)增刪改查操作的詳細(xì)內(nèi)容,更多關(guān)于C++ SQLite數(shù)據(jù)庫(kù)增刪改查的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping
本文主要介紹了C++實(shí)現(xiàn)圖像目標(biāo)區(qū)裁剪ImageCropping,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06C++11標(biāo)準(zhǔn)庫(kù) 互斥鎖 <mutex> 詳解
這篇文章主要介紹了C++11標(biāo)準(zhǔn)庫(kù)互斥鎖 <mutex> 的相關(guān)知識(shí),使用call_once()的時(shí)候,需要一個(gè)once_flag作為call_once()的傳入?yún)?shù),本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-07-07關(guān)于C語(yǔ)言 const 和 define 區(qū)別
這篇文章主要介紹了關(guān)于C語(yǔ)言 const 和 define 區(qū)別 的相關(guān)資料,需要的朋友可以參考下面文章內(nèi)容2021-09-09教你在VS2022?MFC程序中調(diào)用CUDA代碼的方法
這篇文章主要介紹了在VS2022?MFC程序中調(diào)用CUDA代碼,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04解析C++編程中virtual聲明的虛函數(shù)以及單個(gè)繼承
這篇文章主要介紹了C++編程中virtual聲明的虛函數(shù)以及單個(gè)繼承,剖析虛函數(shù)和單個(gè)基類所能夠繼承的成員,要的朋友可以參考下2016-01-01C語(yǔ)言動(dòng)態(tài)順序表實(shí)例代碼
大家好,本篇文章主要講的是C語(yǔ)言動(dòng)態(tài)順序表實(shí)例代碼,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12