如何用C語言操作sqlite3,一文搞懂


sqlite3編程接口非常多,對於初學者來說,我們暫時只需要掌握常用的幾個函數,其他函數自然就知道如何使用了。

數據庫

本篇假設數據庫為my.db,有數據表student。

no name score
4 一口Linux 89.0

創建表格語句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name text, score real);

常用函數

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);
功能:
    打開sqlite數據庫
參數:
	path: 數據庫文件路徑
	db: 指向sqlite句柄的指針,后面對數據庫所有的操作都要依賴這個句柄
返回值:
	成功返回0,失敗返回錯誤碼(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);
功能:
	關閉sqlite數據庫      
返回值:
	成功返回0,失敗返回錯誤碼
const  char  *sqlite3_errmsg(sqlite3 *db);
功能:
	打印錯誤信息        
返回值:
	返回錯誤信息

不使用回調函數執行SQL語句

sqlite3_get_table


int   sqlite3_get_table(sqlite3 *db, const  char  *sql,  char ***resultp,  int*nrow,  int *ncolumn, char **errmsg);
功能:
	執行SQL操作
參數:
	db:數據庫句柄
	sql:SQL語句
	resultp:用來指向sql執行結果的指針
	nrow:滿足條件的記錄的數目
	ncolumn:每條記錄包含的字段數目
	errmsg:錯誤信息指針的地址
返回值:
	成功返回0,失敗返回錯誤碼

舉例

下面比如我們要顯示student表中所有的數據信息,我們就可以利用sqlite3_get_table()執行語句:

select * from student

實現代碼如下:

void do_show_sample(sqlite3 *db)
 {
 	char **result, *errmsg;
	int nrow, ncolumn, i, j, index;

	if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
	{
		printf("error : %s\n", errmsg);
		sqlite3_free(errmsg);
	}
	index = ncolumn;
	for (i=0; i<nrow; i++)
	{
		for (j=0; j<ncolumn; j++)
		{
			printf("%-8s : %-8s\n", result[j], result[index]);		 
			index++;
		}
		printf("************************\n");
	}
	sqlite3_free_table(result);
	return;
 }

假定當前的表格的數據信息如下:

no name score
4 一口Linux 77.0
5 一口peng 88.0
6 一口wang 99.0
7 一口網 66.0

關於這個函數中出現的這些參數的具體含義,我們可以見下圖:

sqlite3編程接口非常多,對於初學者來說,我們暫時只需要掌握常用的幾個函數,其他函數自然就知道如何使用了。

數據庫

本篇假設數據庫為my.db,有數據表student。

no name score
4 一口Linux 89.0

創建表格語句如下:

CREATE TABLE  IF NOT EXISTS student (no integer primary key, name text, score real);

常用函數

sqlite3_open

int   sqlite3_open(char  *path,   sqlite3 **db);
功能:
    打開sqlite數據庫
參數:
	path: 數據庫文件路徑
	db: 指向sqlite句柄的指針
返回值:
	成功返回0,失敗返回錯誤碼(非零值)

sqlite3_close

int   sqlite3_close(sqlite3 *db);
功能:
	關閉sqlite數據庫      
返回值:
	成功返回0,失敗返回錯誤碼
const  char  *sqlite3_errmsg(sqlite3 *db);
功能:
	打印錯誤信息        
返回值:
	返回錯誤信息

不使用回調函數執行SQL語句

sqlite3_get_table


int   sqlite3_get_table(sqlite3 *db, const  char  *sql,  char ***resultp,  int*nrow,  int *ncolumn, char **errmsg);
功能:
	執行SQL操作
參數:
	db:數據庫句柄
	sql:SQL語句
	resultp:用來指向sql執行結果的指針
	nrow:滿足條件的記錄的數目
	ncolumn:每條記錄包含的字段數目
	errmsg:錯誤信息指針的地址
返回值:
	成功返回0,失敗返回錯誤碼

舉例

下面比如我們要顯示student表中所有的數據信息,我們就可以利用sqlite3_get_table()執行語句:

select * from student

實現代碼如下:

void do_show_sample(sqlite3 *db)
 {
 	char **result, *errmsg;
	int nrow, ncolumn, i, j, index;

	if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
	{
		printf("error : %s\n", errmsg);
		sqlite3_free(errmsg);
	}
	index = ncolumn;
	for (i=0; i<nrow; i++)
	{
		for (j=0; j<ncolumn; j++)
		{
			printf("%-8s : %-8s\n", result[j], result[index]);		 
			index++;
		}
		printf("************************\n");
	}
	sqlite3_free_table(result);
	return;
 }

假定當前的表格的數據信息如下:

no name score
4 一口Linux 77.0
5 一口peng 88.0
6 一口wang 99.0
7 一口網 66.0

關於這個函數中出現的這些參數的具體含義,我們可以見下圖:

在這里插入圖片描述

由上圖可知:
代碼中:

ncolumn = 3
nrow    = 5
result 指向所有的結果組成的字符串數組,
各個具體字符串的下標,圖上已經標明。

結合此圖再去理解代碼,就很容易理解代碼的實現原理。

使用回調函數執行SQL語句

sqlite3_exec

typedef  int (*sqlite3_callback)(void *, int, char **, char **);

int   sqlite3_exec(sqlite3 *db, const  char  *sql,  sqlite3_callback callback, void *,  char **errmsg);
功能:
	執行SQL操作
參數:
	db:數據庫句柄
	sql:SQL語句,就是我們前面兩章用於操作表的增刪改查語句
	callback:回調函數
	errmsg:錯誤信息指針的地址
返回值:
	成功返回0,失敗返回錯誤碼

回調函數

typedef  int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);
功能:
	每找到一條記錄自動執行一次回調函數
參數:
	para:傳遞給回調函數的參數
	f_num:記錄中包含的字段數目
	f_value:包含每個字段值的指針數組
	f_name:包含每個字段名稱的指針數組
返回值:
	成功返回0,失敗返回-1

舉例

sqlite3 *db;
char  *errmsg,**resultp;

int callback(void *para, int f_num, char **f_val, char **f_name)
{
	int i;

	for (i=0; i<f_num; i++)
	{
		printf("%-8s", f_val[i]);
	}
	printf("\n");

	return 0;
}

void do_show(sqlite3 *db)
{
	char *errmsg;

	printf("no      name    score\n");
	
	if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0)
	{
		printf("error : %s\n", sqlite3_errmsg(db));
	}
	printf("\n");

	return;
}

回調函數方法實現的代碼,需要實現一個回調函數:callback。
函數sqlite3_exec()在解析命令"select * from student" ,沒獲取到一行數據就會調用一次回調函數,
參考上面的表格student,

callback()總共會被調用5次,
f_num 對應結果的列數,為3
f_value 則指向 每一列對應的值組成的字符串數組

假設現在callback是第四次被調用,如下圖:
在這里插入圖片描述

運行結果

編譯需要使用第三方庫lsqlite3。

gcc student.c -o run -lsqlite3

其他函數

sqlite3 *pdb, 數據庫句柄,跟文件句柄FILE很類似
sqlite3_stmt *stmt, 這個相當於ODBC的Command對象,用於保存編譯好的SQL語句

sqlite3_exec(), 執行非查詢的sql語句
sqlite3_prepare(), 准備sql語句,執行select語句或者要使用parameter bind時,用這個函數(封裝了sqlite3_exec)
Sqlite3_step(), 在調用sqlite3_prepare后,使用這個函數在記錄集中移動

還有一系列的函數,用於從記錄集字段中獲取數據,如

sqlite3_column_text(), 取text類型的數據
sqlite3_column_blob(),取blob類型的數據
sqlite3_column_int(), 取int類型的數據

國際慣例,上完整代碼:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sqlite3.h>

void do_insert(sqlite3 *db)
{
	int no;
	char name[16];
	float score;
	char sqlstr[128], *errmsg;

	printf("input no : ");
	scanf("%d", &no);
	printf("input name : ");
	scanf("%s", name);
	printf("input score : ");
	scanf("%f", &score);
	sprintf(sqlstr, "insert into student values (%d, '%s', %.1f)", 
	no, name, score);
	#if __DEBUG
	printf("cmd:%s\n",sqlstr);
	#endif
	if (sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg) != 0)
	{
		printf("error : %s\n", sqlite3_errmsg(db));
	}
	else
	{
		printf("insert is done\n");
	}
	printf("\n");

	return;
}

void do_delete(sqlite3 *db)
{
	char *errmsg;
	char sqlstr[128], expression[64];

	printf("input expression : ");
	scanf("%s", expression);//name='ma'
	sprintf(sqlstr, "delete from student where %s", expression);
#if __DEBUG
	printf("cmd:%s\n",sqlstr);
#endif
	if (sqlite3_exec(db, sqlstr, NULL, NULL, &errmsg) != 0)
	{
		printf("error : %s\n", sqlite3_errmsg(db));
	}
	else
	{
		printf("deletet is done\n");
	}
	printf("\n");

	return;
}
 
int callback(void *para, int f_num, char **f_val, char **f_name)
{
	int i;

	for (i=0; i<f_num; i++)
	{
		printf("%-8s", f_val[i]);
	}
	printf("\n");

	return 0;
}

void do_show(sqlite3 *db)
{
	char *errmsg;

	printf("no      name    score\n");

	if (sqlite3_exec(db, "select * from student", callback, NULL, &errmsg) != 0)
	{
		printf("error : %s\n", sqlite3_errmsg(db));
	}
	printf("\n");

	return;
}

 void do_show_sample(sqlite3 *db)
 {
 	char **result, *errmsg;
	int nrow, ncolumn, i, j, index;

	if (sqlite3_get_table(db, "select * from student", &result, &nrow, &ncolumn, &errmsg) != 0)
	{
		printf("error : %s\n", errmsg);
		sqlite3_free(errmsg);
	}
	
	index = ncolumn;

	for (i=0; i<nrow; i++)
	{
		for (j=0; j<ncolumn; j++)
		{
			printf("%-8s : %-8s\n", result[j], result[index]);
			
			 
			index++;
		}
		printf("************************\n");
	}
	sqlite3_free_table(result);

	return;
 }
 

int main()
{
	sqlite3 *db;
	int n;
	char clean[64];

	if (sqlite3_open("my.db", &db) < 0)
	{
		printf("fail to sqlite3_open : %s\n", sqlite3_errmsg(db));
		return -1;
	}

	while ( 1 )
	{
		printf("*********************************************\n");
		printf("1: insert record   \n2: delete record  \n3: show record  \n4: quit\n");
		printf("*********************************************\n");
		printf("please select : "); 
		
		if (scanf("%d", &n) != 1)
		{
			fgets(clean, 64, stdin);
			printf("\n");
			continue;
		}
		switch ( n )
		{
			case 1 :
				do_insert(db);
				break;
			case 2 :
				do_delete(db);
				break;
			case 3 :
				do_show_sample(db);
				break;
			case 4 :
				sqlite3_close(db);
				exit(0);
		}
	}
	return 0;
}

運行主頁面:
在這里插入圖片描述

插入記錄:
在這里插入圖片描述
顯示記錄:
在這里插入圖片描述
刪除記錄:
在這里插入圖片描述

完整代碼,請關注公眾號「一口Linux」


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM