資料庫 sqlite3_get_table,sqlite3_free_table

weixin_30639719發表於2020-04-05

sqlite入門基礎(二):sqlite3_get_table,sqlite3_free_table

 http://www.cnblogs.com/likebeta/archive/2012/06/17/2552784.html
 

上一篇介紹的sqlite3_exec 是使用回撥來執行對select結果的操作。還有一個方法可以直接查詢而不需要回撥。但是,我個人感覺還是回撥好,因為程式碼可以更加整齊,只不過用回撥很麻煩,你得宣告一個函式,如果這個函式是類成員函式,你還不得不把它宣告成static的(要問為什麼?這又是C++基礎了。C++成員函式實際上隱藏了一個引數:this,C++呼叫類的成員函式的時候,隱含把類指標當成函式的第一個引數傳遞進去。結果,這造成跟前面說的sqlite 回撥函式的引數不相符。只有當把成員函式宣告成static 時,它才沒有多餘的隱含的this引數)。
雖然回撥顯得程式碼整齊,但有時候你還是想要非回撥的select 查詢。這可以通過sqlite3_get_table 函式做到。

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

第1個引數不再多說,看前面的例子。
第2個引數是sql 語句,跟sqlite3_exec 裡的sql 是一樣的。是一個很普通的以\0結尾的char*字串。
第3個引數是查詢結果,它依然一維陣列(不要以為是二維陣列,更不要以為是三維陣列)。它記憶體佈局是:欄位名稱,後面是緊接著是每個欄位的值。下面用例子來說事。
第4個引數是查詢出多少條記錄(即查出多少行,不包括欄位名那行)。
第5個引數是多少個欄位(多少列)。
第6個引數是錯誤資訊,跟前面一樣,這裡不多說了。

pazResult返回的字串數量實際上是(*pnRow+1)*(*pnColumn),因為前(*pnColumn)個是欄位名

修改上篇的例子,使用sqlite3_get_table,來去的結果集:

#include <iostream>
using namespace std;
#include "sqlite/sqlite3.h"
int callback(void*,int,char**,char**);
int main()
{
    sqlite3* db;
    int nResult = sqlite3_open("test.db",&db);
    if (nResult != SQLITE_OK)
    {
        cout<<"開啟資料庫失敗:"<<sqlite3_errmsg(db)<<endl;
        return 0;
    }
    else
    {
        cout<<"資料庫開啟成功"<<endl;
    }

    char* errmsg;

    nResult = sqlite3_exec(db,"create table fuck(id integer primary key autoincrement,name varchar(100))",NULL,NULL,&errmsg);
     if (nResult != SQLITE_OK)
     {
         sqlite3_close(db);
         cout<<errmsg;
         sqlite3_free(errmsg);
        return 0;
    }
    string strSql;
    strSql+="begin;\n";
    for (int i=0;i<100;i++)
    {
        strSql+="insert into fuck values(null,'heh');\n";
    }
    strSql+="commit;";
    //cout<<strSql<<endl;

    nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,&errmsg);

    if (nResult != SQLITE_OK)
    {
        sqlite3_close(db);
        cout<<errmsg<<endl;
        sqlite3_free(errmsg);
        return 0;
    }

    strSql = "select * from fuck";
    //nResult = sqlite3_exec(db,strSql.c_str(),callback,NULL,&errmsg);
    char** pResult;
    int nRow;
    int nCol;
    nResult = sqlite3_get_table(db,strSql.c_str(),&pResult,&nRow,&nCol,&errmsg);
      if (nResult != SQLITE_OK)
    {
        sqlite3_close(db);
        cout<<errmsg<<endl;
        sqlite3_free(errmsg);
        return 0;
    }

    string strOut;
    int nIndex = nCol;
    for(int i=0;i<nRow;i++)
    {
        for(int j=0;j<nCol;j++)
        {
            strOut+=pResult[j];
            strOut+=":";
            strOut+=pResult[nIndex];
            strOut+="\n";
            ++nIndex;
        }
    }
    sqlite3_free_table(pResult);
    cout<<strOut<<endl;
    sqlite3_close(db);
    return 0;
}
/*
int callback(void* ,int nCount,char** pValue,char** pName)
{
    string s;
    for(int i=0;i<nCount;i++)
    {
        s+=pName[i];
        s+=":";
        s+=pValue[i];
        s+="\n";
    }
    cout<<s<<endl;
    return 0;
}*/

轉載於:https://www.cnblogs.com/vipwtl/p/5916969.html

相關文章