SQlite資料庫的C編程介面(五)
便捷函數(Convenience Functions) by斜風細雨QQ:253786989 2012-02-07
SQlite擁有很多早期遺留下來的便捷函數,這些函數存在很多缺點。當然他們依然存在就有理由——使用方便。
它們的優點也僅僅是使用方便,而不是具有很好的效能。相反,它們的效能會比直接調用PUBLIC API函數更差一些。對於這些便捷函數,它們並沒有什麼特別之處,只是在這些函數內部調用sqlite3_prepare_xxx、sqlite3_step、sqlite3_finalize等API函數來完成一站式功能。在這樣的函數內部往往存在很多額外的類型轉換,所以這些函數很可能會比我們自己去調用sqlite3_prepare_xxx、sqlite3_step、sqlite3_finalize等API執行的更慢一些。
其次,這些API不支援參數綁定。就像上一篇筆記中介紹的,這樣的程式更容易遭到“SQL注入攻擊”,安全性更差。
總之,作者Jay A. Kreibich非常不推薦使用這些便捷函數。正如他說的:“If you’re just trying to throw together a quick and dirty snippet of code,these functions provide an easy means of doing that.I strongly recommend using the normal prepare, step, and finalize routines. You’ll end up with safer code and better performance.”
(1)
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 */);
預先處理(prepare)和執行(execute)一條或多條SQL語句,對結果集的每一行調用其第3個參數所指向的回呼函數。第1個參數指向一個有效資料庫連接。第2個參數是UTF-8編碼的SQL語句(可以包含一條,或多條:以分號隔開)。第3個參數是一個指向回呼函數的指標,如果不需要使用回呼函數,可以給該參數傳遞NULL。第4個參數也是一個指標,用來傳遞使用者資料到回呼函數。需要注意的是,比如該指標由sqlite3_malloc獲得,則要在其不再使用時調用sqlite3_free函數釋放。第5個參數是一個指向指標的指標,通過該參數返回錯誤碼。如果在sqlite3_exec執行過程中,沒有遇到任何錯誤,最後函數將返回SQLITE_OK。
比如sqlite3_exec正在執行SELECT查詢操作,而且想對返回結果進行處理。那就要傳遞一個回呼函數給sqlite3_exec。這樣sqlite3_exec函數每次擷取一行資料,就會調用該回呼函數。如果sqlite3_exec正在執行的操作不返回資料,就直接給sqlite3_exec函數的第3個參數傳遞NULL就可以了。
回呼函數原型:
int user_defined_exec_callback( void *userData, int numCol, char **colData, char **colName )
第1個參數對應於sqlite3_exec函數的第4個參數,用於傳遞使用者資料。第2個參數指明結果集中一共有多少列。第3個參數儲存當前資料行的資料,第4個參數儲存當前資料行的所有列的列名。第3個參數和第4個參數都是以字串的形式返回。
正常情況下,回呼函數應該返回0,如果它返回一個非0值,則sqlite3_exec函數將終止執行,並返回SQLITE_ABORT錯誤碼。
(2)
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 */);
這個函數與sqlite3_exec函數不同,它只在SQL命令字串執行完成之後,返回全部的結果資料。該函數是專門針對SELECT語句設計的。
第1個參數是指向資料庫連接的指標。第2個參數是UTF-8編碼的SQL命令字串。第3個參數看起來有點複雜,通過該參數返回SQL語句執行結果。首先該參數是一個指標,它指向一個一維數組,這個一維數組裡面儲存的元素類型是字串指標。第4個和第5個參數返回結果集中的行數和列數。最後一個參數返回錯誤碼。
函數執行完成返回的結果集中,包含(nColumn * (nRow + 1))個資料項目。其中多出來的一行是列名,剩下的nColumn*nRom項是資料。
如果sqlite3_get_table函數執行過程中沒遇到任何錯誤,最後會返回SQLITE_OK。
下面是對結果集的一個訪問例子,擷取結果集中第R行,第C列的資料:
/* offset to access column C of row R of **result */int offset = ((R + 1) * numCol) + C;char *value = result[offset];
傳遞給sqlite3_get_table函數的SQL命令字串可以包含多條SELECT語句。但是,對於這多條SELECT語句的返回結果全部儲存在pazResult所指向的一維數組中。沒有辦法確定一維數組中,哪些行資料是哪個SELECT語句檢索出來的。並且所有的SELECT語句所返回的列數必須相同,否則sqlite3_get_table函數執行失敗。除此之外,只有第一條語句會返回列名,儲存在結果集一維數組的第一行中。基於以上原因,最好在每次調用sqlite3_get_table函數時使用單獨一條SQL命令。
(3)
void sqlite3_free_table(char **result);
由sqlite3_get_table函數返回的結果集,所佔用的記憶體,需要由sqlite3_free_table函數來釋放。
SQlite資料庫的C編程介面(五)
便捷函數(Convenience Functions) by斜風細雨QQ:253786989 2012-02-07