sqlite3入門基礎、sqlite3常用函式
1、開啟/建立一個數據庫
int sqlite3_open(const char *filename, sqlite3 **ppDb );
功能:開啟資料庫連結
引數:filename:資料庫的路徑和檔名
ppdb:資料庫控制代碼。
返回:成功 SQLITE_OK (值為0),否則返回其他值。
2、回撥函式執行sql語句
int sqlite3_exec(sqlite3* pDB, const char *sql, sqlite_callback callback, void*para, char** errMsg);
功能:編譯和執行零個或多個SQL 語句,查詢的結果返回給回撥函式callback
引數:
pDB,資料庫控制代碼。
sql,待執行的SQL 語句字串,以’\0’結尾。
callback,回撥函式,用來處理查詢結果,如果不需要回調(比如做insert 或者delete 操作時),可以輸入NULL。
para,要傳入回撥函式的指標引數,沒有可以置為NULL。
errMsg,返回錯誤資訊,注意是指標的指標。
返回值:執行成功返回SQLITE_OK,否則返回其他值
3、回撥函式
typedef int (*sqlite_callback)(void* para, int columnCount, char** columnValue,
char** columnName);
功能:由使用者處理查詢的結果
引數:
para,從sqlite3_exec()傳入的引數指標;
columnCount, 查詢到的這一條記錄有多少個欄位(即這條記錄有多少列);
columnValue,查詢出來的資料都儲存在這裡,它實際上是個1 維陣列(不要以為是2 維陣列),每一個元素都是一個char * 值,是一個欄位內容(用字串來表示,以‘\0’結尾);
columnName,與columnValue 是對應的,表示這個欄位的欄位名稱。
返回值:執行成功返回SQLITE_OK,否則返回其他值
4、關閉
int sqlite3_close(sqlite3 *ppDb);
功能:關閉資料庫。
引數:ppdb:資料庫控制代碼。
5、釋放
void sqlite3_free(void * errMsg );
功能:釋放存放錯誤資訊的記憶體空間
引數:errMsg: 返回錯誤資訊
6、 非回撥來執行sql語句
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 */ );
功能:非回撥來執行sql語句
db:資料庫控制代碼
zSql:要執行的SQL語句
pazResult:查詢結果,一維陣列
pnRow:查詢出多少條記錄(查出多少行)
pnColumn:多少個欄位(查出多少列)
pzErrmsg:錯誤資訊
返回值:執行成功返回SQLITE_OK,否則返回其他值
注:pazResult的欄位值是連續的,是以為陣列不是二維陣列,從第0索引到第 pnColumn- 1索引都是欄位名稱,從第 pnColumn索引開始,後面都是欄位。
7、釋放pazResult查詢結果
sqlite3_free_table(char ***pazResult);
引數:pazResult:查詢結果,一維陣列
例子:
選課管理系統
- 支援學生資訊錄入功能 學生表(學生學號,學生姓名,學生性別, 健康指數<int>)。
- 支援老師資訊錄入功能 教師表(老師ID,老師姓名,老師性別, 課程名字) 一個老師只會教一門課。
- 支援學生資訊查詢功能(全查詢,按性別分組查詢group by,按學號降序查詢order by,按性別分組查詢男女各自的健康總指數 group by , having,模糊查詢學號like)單表查詢。
- (擴充套件)支援學生選課功能(可以選哪個老師上課) 選課表 (學生學號,老師ID)。
- (擴充套件)支援選課結果查詢功能 join 。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "/home/sqlite/include/sqlite3.h"
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i<argc;i++)
{
printf("%s = %s\r\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\r\n");
return 0;
}
void input_student_info(char *dbName){
sqlite3 *db; //sqlite3的資料庫控制代碼
char *zErrMsg = 0; //錯誤資訊
char *sql = NULL;
sql = (char *) malloc(sizeof(char)*100);//開闢快取
char *sel = NULL;
int id;
int rc;
char name[20];
char sex[5];
int health;
rc = sqlite3_open(dbName, &db); //開啟資料庫
if( rc ){ //成功為SQLITE_OK(值為0)
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db); //關閉資料庫
return;
}
printf("\n");
printf("id(0000~9999)= ");
scanf("%d", &id);
printf("name= ");
scanf("%s", name);
printf("sex(m:man,w:women)=");
scanf("%s", sex);
printf("health(0~10)= ");
scanf("%d", &health);
sprintf(sql, "INSERT INTO 'Student' VALUES(%d, '%s', '%s', %d);", id, name, sex, health);
sqlite3_exec( db , sql , callback , 0 , &zErrMsg );
printf("SELECT:\n");
sel = "SELECT * FROM Student;";
sqlite3_exec( db , sel , callback , 0 , &zErrMsg );
sqlite3_close(db);
if(sql !=NULL){
free(sql);
}
}
void input_teacher_info(char *dbName){
sqlite3 *db; //sqlite3的資料庫控制代碼
char *zErrMsg = 0; //錯誤資訊
char *sql = NULL;
sql = (char *) malloc(sizeof(char)*100);//開闢快取
char *sel = NULL;
int rc;
int id;
char name[20];
char sex[5];
char course[20];
rc = sqlite3_open(dbName, &db); //開啟資料庫
if( rc ){ //成功為SQLITE_OK(值為0)
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db); //關閉資料庫
return;
}
printf("\n");
printf("id(0000~9999) =");
scanf("%d", &id);
printf("name =");
scanf("%s", name);
printf("sex(m:man,w:women) =");
scanf("%s", sex);
printf("course(Math,Chinese,English)=");
scanf("%s", course);
sprintf(sql, "INSERT INTO 'Teacher' VALUES(%d, '%s', '%s', '%s');", id, name, sex, course);
sqlite3_exec( db , sql , callback , 0 , &zErrMsg );
printf("SELECT:\n");
sel = "SELECT * FROM Teacher;";
sqlite3_exec( db , sel , callback , 0 , &zErrMsg );
sqlite3_close(db);
if(sql !=NULL){
free(sql);
}
}
void select_info(char *dbName){
sqlite3 *db; //sqlite3的資料庫控制代碼
char *zErrMsg = 0; //錯誤資訊
int cmd2,rc;
rc = sqlite3_open(dbName, &db); //開啟資料庫
if( rc ){ //成功為SQLITE_OK(值為0)
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db); //關閉資料庫
return;
}
while(1){
printf("Please choose: \n \
1:select all information \n \
2:select by sex \n \
3:select by id DESC \n \
4:select by health \n \
5:like select by id \n \
0:quit \n");
scanf("%d",&cmd2);
switch(cmd2){
case 1:{
char *sql1="SELECT * FROM Student;";
sqlite3_exec(db, sql1, callback, 0, &zErrMsg);
break;
}
case 2:{
printf("intput sex(m:man,w:women):");
char s;
int r;
setbuf(stdin,NULL);//清快取,如果不清除則會讀取上次快取中的'\n'
r = scanf("%c",&s);
//printf("r=%d\n",r);
char sql2[100]={};
sprintf(sql2, "SELECT * FROM 'Student' WHERE sex = '%C';",s);
sqlite3_exec(db, sql2, callback, 0, &zErrMsg);
break;
}
case 3:{
char *sql3="SELECT * FROM Student ORDER BY id DESC;";
sqlite3_exec(db, sql3, callback, 0, &zErrMsg);
break;
}
case 4:{
printf("intput sex(m:man,w:women):");
char sql4[100]={};
char c;
setbuf(stdin,NULL);
scanf("%c",&c);
sprintf(sql4, "SELECT SUM(health) FROM Student GROUP BY sex having sex = '%c';",c);
sqlite3_exec(db, sql4, callback, 0, &zErrMsg);
break;
}
case 5:{
printf("intput id:");
char sql5[100]={};
int i;
setbuf(stdin, NULL);
scanf("%d",&i);
sprintf(sql5, "SELECT * FROM Student WHERE id LIKE '%%%d%%';", i);//注意%
sqlite3_exec(db, sql5, callback, 0, &zErrMsg);
break;
}
case 0:{
//break;
return;
}
default:{
printf("please choose right num\n");
break;
}
}
}
sqlite3_close(db);
}
void select_course(char *dbName){
sqlite3 *db; //sqlite3的資料庫控制代碼
char *zErrMsg = 0; //錯誤資訊
char *sel = NULL;
char *sel2 = NULL;
char *sql = NULL;
int cmd3,rc, ret;
int stu_id, teacher_id,flag=0;
int i, j;
int nRow, nCol;
char **azResult;
sql = (char *) malloc(sizeof(char)*100);//開闢快取
rc = sqlite3_open(dbName, &db); //開啟資料庫
if( rc ){ //成功為SQLITE_OK(值為0)
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db); //關閉資料庫
return;
}
start:
printf("input student id:");
scanf("%d",&stu_id);
sel = "SELECT * FROM Student;";
sqlite3_get_table(db, sel, &azResult, &nRow, &nCol, &zErrMsg);
// azResult的欄位值是連續的,從第0索引到第 nCol - 1索引都是欄位名稱,從第 nCol 索引開始,後面都是欄位值
for(i=1; i <= nRow; i++){
//printf("id=%s\n",azResult[i*nCol]);
if(atoi(azResult[i*nCol]) == stu_id){
printf("find the student id=%d\n",stu_id);
flag =1;
break;
}
}
if(0 == flag){
printf("please input right student id\n");
goto start;
}
if(1 == flag){
sel2 = "SELECT * FROM Teacher;";
printf("\n******the teacher info:******\n");
sqlite3_exec(db, sel2, callback, 0, &zErrMsg);
printf("*******************************\n");
printf("please choose teacher id:");
scanf("%d",&teacher_id);
sprintf(sql, "INSERT INTO Course VALUES('%d', '%d');", stu_id, teacher_id);
ret = sqlite3_exec(db, sql, callback, 0, &zErrMsg);
if(ret == SQLITE_OK){
printf("select success\n\n");
}
if(ret!=SQLITE_OK){
fprintf(stderr, "SQL error: %s\n\n", zErrMsg);
sqlite3_free(zErrMsg);
}
}
sqlite3_free_table(azResult);//釋放查詢結果
sqlite3_close(db);
}
void select_all(char *dbName){
sqlite3 *db; //sqlite3的資料庫控制代碼
char *zErrMsg = 0; //錯誤資訊
char *sql = NULL;
int rc,sel_id;
sql = (char *) malloc(sizeof(char)*100);//開闢快取
rc = sqlite3_open(dbName, &db); //開啟資料庫
if( rc ){ //成功為SQLITE_OK(值為0)
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db); //關閉資料庫
return;
}
printf("please choose \n \
1:select result by student id \n \
2:select result by teacher id \n \
0:quit \n");
start:
setbuf(stdin,NULL);
scanf("%d",&sel_id);
switch(sel_id){
case 1:{
printf("student id:");
int stu_id;
setbuf(stdin,NULL);
scanf("%d",&stu_id);
sprintf(sql, "SELECT * FROM Student LEFT JOIN Course ON Student.ID = Course.StuID WHERE Student.ID='%d'",stu_id);
sqlite3_exec( db , sql , callback ,0, &zErrMsg );
break;
}
case 2:{
printf("teacher id:");
int teacher_id;
setbuf(stdin,NULL);
scanf("%d",&teacher_id);
sprintf(sql, "SELECT * FROM Teacher LEFT JOIN Course ON Teacher.ID = Course.TeacherID WHERE Teacher.ID='%d'",teacher_id);
sqlite3_exec( db , sql , callback ,0, &zErrMsg );
break;
}
case 0:{
return;
}
default:{
printf("please input right num\n");
goto start;
}
}
sqlite3_close(db);
}
// ./main ./data.db
int main(int argc, char **argv){
sqlite3 *db; //sqlite3的資料庫控制代碼
char *zErrMsg = 0; //錯誤資訊
int cmd, rc;
char *sel = NULL;
if( argc!=2 ){
fprintf(stderr, "Usage: %s DATABASE \n", argv[0]);//stderr是Unix中的標準輸出
return 0;
}
rc = sqlite3_open(argv[1], &db); //開啟資料庫
if( rc ){ //成功為SQLITE_OK(值為0)
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db); //關閉資料庫
return 0;
}
//學生資訊表
char *sql = " CREATE TABLE Student( \
ID INTEGER PRIMARY KEY, \
Name VARCHAR(20), \
Sex VARCHAR(5), \
Health INTEGER \
);";
sqlite3_exec( db , sql , callback ,0, &zErrMsg );
//老師資訊表
sql = " CREATE TABLE Teacher( \
ID INTEGER PRIMARY KEY, \
Name VARCHAR(20), \
Sex VARCHAR(5), \
CourseName VARCHAR(20) \
);";
sqlite3_exec( db , sql , callback ,0, &zErrMsg );
//課程資訊表
sql = " CREATE TABLE Course( \
StuID INTEGER, \
TeacherId INTEGER \
);";
sqlite3_exec( db , sql , callback ,0, &zErrMsg );
while(1)
{
//start:
printf("Please choose: \n \
1:Input student information \n \
2:Input teacher information \n \
3:Information query function \n \
4:select Teacher Course \n \
5:select all Course \n \
0:quit \n");
scanf("%d", &cmd);
switch(cmd){
case 1:{
input_student_info(argv[1]);
break;
}
case 2:{
input_teacher_info(argv[1]);
break;
}
case 3:{
select_info(argv[1]);
break;
}
case 4:{
select_course(argv[1]);
break;
}
case 5:{
select_all(argv[1]);
break;
}
case 0:{
goto end;
//break;
}
default:{
printf("please choose right num\n");
break;
}
}
}
end:
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);//釋放存放錯誤資訊的記憶體空間
}
sqlite3_close(db);//關閉
return 0;
}