日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 程序喵大人


我在客戶端開發(fā)時由于需要使用數(shù)據(jù)庫,于是選擇了輕巧的sqlite數(shù)據(jù)庫研究了一下,今天在這里和大家分享下我總結(jié)的sqlite使用文檔。

源碼下載
wget http://www.sqlite.org/2017/sqlite-autoconf-3160200.tar.gz
tar xvzf sqlite-autoconf-3160200.tar.gz
交叉編譯
./configure --host=arm-himix200-linux --prefix=/home/zjucad/wangzhiqiang/toolDir/sqlite-autoconf-3160200/libs
make
make install

按順序執(zhí)行上述命令后sqlite的鏈接庫和頭文件等就會出現(xiàn)在prefix目錄下

api使用

基本的使用流程

sqlite3_open()->sqlite3_prepare_v2()->sqlite3_step()->sqlite3_column()->sqlite3_finalize()->sqlite3_close()

具體介紹:

int sqlite3_open(
 const char *filename,   /* Database filename (UTF-8) */
 sqlite3 **ppDb          /* OUT: SQLite db handle */
);
打開一個數(shù)據(jù)庫,第一個參數(shù)為數(shù)據(jù)庫的路徑,注意這里不能為:memory:,這表示存在內(nèi)存中,第二個參數(shù)為返回,返回這個數(shù)據(jù)庫的handle,函數(shù)返回值是int,成功則返回SQLITE_OK,失敗的話可以通過sqlite3_errmsg()查看錯誤信息。
注:sqlite還有個sqlite3_open_v2()函數(shù),添加一些flag,看著不太常用。
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 */
);
準備數(shù)據(jù)庫語句的上下文,相當于編譯sql語句,最后由step函數(shù)執(zhí)行編譯好的語句,ppStmt需要自己首先定義好,最后一個參數(shù)基本傳NULL。
注:sqlite還有個sqlite3_prepare()函數(shù),但是現(xiàn)在官方推薦使用v2版本,有錯誤v2版本能夠立即暴露出來。

一般使用sqlite3_prepare_v2()都是和sqlite3_bind_xxx()系列函數(shù)一起使用,例如執(zhí)行插入語句,使用sqlite3_bind_xxx()可以動態(tài)綁定某些參數(shù)的值,后續(xù)給出示例代碼。

int sqlite3_step(sqlite3_stmt*);
執(zhí)行數(shù)據(jù)庫語句
int sqlite3_reset(sqlite3_stmt *pStmt);
重置數(shù)據(jù)庫上下文,當需要重新bind參數(shù)時可以使用這個函數(shù),避免多次prepare。
int sqlite3_finalize(sqlite3_stmt *pStmt);
刪除數(shù)據(jù)庫語句的上下文,調(diào)用了sqlite3_prepare_v2()后無論成功失敗都需要調(diào)用,避免內(nèi)存泄漏。
int sqlite3_close(sqlite3 *);
關(guān)閉數(shù)據(jù)庫

在執(zhí)行查詢操作時,可能結(jié)果不止一條,那sqlite3_step()函數(shù)就會返回SQLITE_ROW直到所有結(jié)果都被查詢到會返回SQLITE_DONE,這里每次sqlite3_step()返回SQLITE_ROW后都需要再次調(diào)用返回下一次查詢的結(jié)果。

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
double sqlite3_column_double(sqlite3_stmt*, int iCol);
int sqlite3_column_int(sqlite3_stmt*, int iCol);
sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
int sqlite3_column_type(sqlite3_stmt*, int iCol);
sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);

執(zhí)行查詢語句后需要使用這類函數(shù),獲取查詢到的結(jié)果,第二個參數(shù)代表第幾列,需要根據(jù)數(shù)據(jù)庫表的每一列具體類型調(diào)用相應(yīng)的函數(shù),可以通過sqlite3_column_type()獲取某一列的類型,通過sqlite3_column_count()函數(shù)獲取這次查詢結(jié)果共有多少列。

在一些簡單的場景下也可以使用sqlite3的wrapper函數(shù)
主要有sqlite3_exec()和sqlite3_get_table()函數(shù),相當于調(diào)用了sqlite3_prepare_v2()->sqlite3_step()->sqlite3_finalize()這個流程。

區(qū)別是sqlite3_exec()在查詢中需要添加回調(diào)函數(shù),sqlite3_get_table()主要用在查詢上,沒有回調(diào),會把查詢到的結(jié)果存到一塊地址。

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

注意這里的最后一個參數(shù)是錯誤信息,如果執(zhí)行函數(shù)沒有返回SQLITE_OK,可以查看errmsg處的信息,這塊內(nèi)存也需要自己手動調(diào)用sqlite3_free()來釋放。
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 */
);
void sqlite3_free_table(char **result);

sqlite3_get_table()主要用在查詢上,會把查詢到的結(jié)果存到一塊地址。由調(diào)用者手動調(diào)用sqlite3_free_table()釋放內(nèi)存。

注意事項

  • sqlite3-column-text()等函數(shù)返回的地址不需要自己free,sqlite會在調(diào)用sqlite3_step() or sqlite3_reset() or sqlite3_finalize()時自動釋放

  • 如何設(shè)置自增字段
    字段是integer 的primary key就會自增

    CREATE TABLE t1(
    a INTEGER PRIMARY KEY,
    b INTEGER
    );

    如上代碼,字段a就會自增,最大值是9223372036854775807,如果insert超過了這個數(shù)量,就會返回SQLITE_FULL錯誤,但90%的數(shù)據(jù)庫行數(shù)可能不會超過這個數(shù)量。

示例代碼

sqlite3 *db_;
std::string sql =
 "create table if not exists sqlite("
 "id INTEGER primary key     AUTOINCREMENT,"
 "value      int64      not null);";
char *err_msg = NULL;
int ret = sqlite3_exec(db_, sql.c_str(), NULL, 0, &err_msg);
if (ret != SQLITE_OK) {
 std::cout << "create table error " << err_msg;
 sqlite3_free(err_msg);
 return false;
}
std::string sql =
 "insert into sqlite(value) values(?1)";
sqlite3_stmt *stmt;
int ret = sqlite3_prepare_v2(db_, sql.c_str(), -1, &stmt, NULL);
if (ret != SQLITE_OK) {
 std::cout << "prepare sql error " << ret << " " << sqlite3_errcode(db_);
 return false;
}
if (sqlite3_bind_int64(stmt, 1, 1) != SQLITE_OK) {
 std::cout << "bind timestamp error " << sqlite3_errcode(db_);
 return false;
}
if (sqlite3_step(stmt) != SQLITE_DONE) {
 std::cout << "step insert fail " << sqlite3_errcode(db_);
 return false;
}
sqlite3_finalize(stmt);
本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉