嵌入式數據庫--SQLite簡單應用(一)

簡介html

 嵌入式數據庫其實是輕量級的,在運行時,它們須要較少的內存。
嵌入式數據庫的一大好處就是在你的程序內部不須要網絡配置,也不須要管理。由於客戶端和服務器在同一進程空間運行。
SQLite 的數據庫權限只依賴於文件系統,沒有用戶賬戶的概念。SQLite 有數據庫級鎖定,沒有網絡服務器。
它須要的內存,其它開銷很小,適合用於嵌入式設備。你須要作的僅僅是把它正確的編譯到你的程序。
接口由SQLite C API組成,也就是說無論是程序、腳本語言仍是庫文件,最終都是經過它與SQLite交互的(咱們一般用得較多的ODBC/JDBC最後也會轉化爲相應C API的調用)。sql

http://www.sqlite.org/download.html
下載sqlite-src-3070900shell

咱們不須要TCL的支持,在編譯時須要把TCL支持disable了
 ./configure –disable-tcl
 make
 生成的庫(動態庫、靜態庫)和可執行程序都在 .libs目錄下數據庫


在shell下命令express

建一個數據庫編程

sqlite3 stu.db數組

進入了sqlite3以後,會看到如下文字:服務器

SQLite version 3.1.3
Enter ".help" for instructions
sqlite> 網絡

創建一個表,名爲stu,有name和num兩個字段,以;分號結束數據結構

CREATE TABLE student(name,num);

列出全部的數據表: .tables

.tables

student
顯示數據庫結構:.schema

.schema student

CREATE TABLE student(name,num);

插入幾個數據   insert into table_name values(data1, data2, data3, ...);

insert into stu values('Stevenbai'1,001);
insert into stu values(anjincang,1002);

查詢  基本語法 select columns from table_name where expression;

導出全部數據庫的內容

select * from film;

Stevenbai|1001
anjincang|1002

 

 SQLite編程與應用

打開數據庫
int sqlite3_open(const char *filename, sqlite3 **ppDb);
第一個參數指文件名
第二個參數則是定義的 sqlite3 ** 結構體指針(關鍵數據結構),稱爲數據庫句柄。
返回值:表示操所是否正確 (SQLITE_OK 操做正常)
說明:打開一個數據庫,文件名不必定要存在,若是此文件不存在,sqlite會自動建立。

關閉數據庫
int sqlite3_close(sqlite3*);
參數就是剛纔的結構體,也就是數據庫句柄。
說明:若是用sqlite3_open開啓了一個數據庫,結尾時不要忘了用這個函數關閉數據庫。

 

執行SQL語句
int sqlite3_exec(sqlite3*,const char *sql,sqlite_callback,void *,char **errmsg);
這個函數的功能是執行一條或者多條SQL語句,SQL語句之間用「;」號隔開。
建議在執行一條或者多條SQL語句得時候,指定第三個參數回調函數,在回調函數中能夠得到執行Sql得詳細過程,若是全部Sql執行完畢則應該返回0,不然,則說明此次執行並無徹底成功。第五個參數:若是執行失敗(沒有返回0)則能夠查看第五個闡述得值。來查看詳細錯誤信息。。
說明:一般sqlite3_callback和它後面的void*這兩個位置均可以填NULL,表示不須要回調。好比您作insert操做,作delete操做,就沒有必要使用回調。而看成select時,就要使用回調,由於sqlite3把數據查出來,得經過回調告訴你查出了什麼數據。

exec的回調
typedef int (*sqlite3_callback)(void*, int, char**, char**);
例如:int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name )
para是在 sqlite3_exec 裏傳入的 void * 參數,經過para參數,能夠傳入帶有控制功能的數據
n_column是這一條記錄有多少個字段 (即這條記錄有多少列)
char ** column_value 是個關鍵值,查出來的數據都保存在這裏,它其實是個1維數組,每個元素都是一個 char * 值,是一個字段內容(用字符串來表示,以\0結尾)
char ** column_name跟column_value是對應的,表示這個字段的字段名稱
說明:回調函數必須定義爲上面這個函數的類型。

 取當前插入位置:
long long int sqlite3_last_insert_rowid(sqlite3*);
返回你前一次插入得位置,從1開始,sqlite3* 爲你打開數據庫所獲得得句柄。

非回調select查詢:
int sqlite3_get_table(sqlite3*,const char *sql,char ***resultp,int *nrow,int *ncolumn,char **errmsg);
執行一次查詢Sql 而且返回獲得一個記錄集。
說明:第三個參數是查詢結果,它是一維數組,內存佈局爲:第一行是字段名稱,後面是緊接着是每一個字段的值。

 

釋放查詢結果:
void sqlite3_free_table(char **result);
釋放當前查詢的記錄集所佔用的內存。

 

#include<stdio.h>
#include<sqlite3.h>
#include<string.h>

int printSqlResult(void *para, int column, char **value, char **key)
{
    int i;
    printf("column=%d\n",column);
    for(i = 0; i < column; i++)
    {
        printf("%s\t",*(value+i));
    }
    printf("\n");
    return SQLITE_OK;
}
int main(int argc, char *argv[])
{
    sqlite3 *pDb;
    int j, i, pos, row, col, ret;
    char acCmd[128];
    char **ppRet;

    if(argc < 2)
    {
        printf("please input sql command!");
        return -1;
    }
    
    strcpy(acCmd,argv[1]);

    ret = sqlite3_open("./stu.db",&pDb);
    if(ret != SQLITE_OK)
    {
        printf("open database fail!\n");
        return -1;
    }

    ret = sqlite3_exec(pDb, acCmd, printSqlResult, NULL, NULL);
    {
        if(ret != SQLITE_OK)
        {
            printf("exec fail,ret %d\n", ret);
            return -1;
        }
    }
    pos = sqlite3_last_insert_rowid(pDb);
    printf("pos = %d\n",pos);

    sqlite3_get_table(pDb,"select * from stu;",&ppRet,&row,&col,NULL);

    for(i = 0; i <= row; i++)
    {
        for(j = 0; j < col; j++)
        {
            printf("%s\t",*(ppRet+i*col+j));
        }
        printf("\n");
    }
    sqlite3_free_table(ppRet);
    sqlite3_close(pDb);
    return 0;
}


[root@localhost sqlite]# ./sqlite "select * from stu;"

column=2

Stevenbai       1001

column=2

anjincang       1002

pos = 0

name    num

Stevenbai       1001

anjincang       1002

回調函數打印完一條信息再回調,看column=2打印了兩次就知道。