嵌入式linux-sqlite3数据库,数据库基本知识,sqlite3系统命令,sqlite3 SQL命令,SQLite编程接口

1,数据库基本概念:数据(Data)、数据库 (Database)

  1. 数据(Data)
    能够输入计算机并能被计算机程序识别和处理的信息集合
  2. 数据库 (Database)
    数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合

2,常用的数据库

  1. 大型数据库
    ·Oracle公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作系统平台。目前Oracle关系数据库产品的市场占有率名列前茅。
    ·IBM 的DB2是第一个具备网上功能的多媒体关系数据库管理系统,支持包Linux在内的一系列平台。

    关系型数据库是在建立表格的时候, 数据与数据之间是依靠逻辑关系建立起来数据的存储关系

  2. 中型数据库
    Server是微软开发的数据库产品,主要支持windows平台。
  3. 小型数据库
    mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,2008年被Sun公司收购,开放源码。

3,基于嵌入式的数据库

  1. 基于嵌入式Linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB
  2. Firebird是关系型数据库,功能强大,支持存储过程、SQL兼容等
  3. SQLite关系型数据库,体积小,支持ACID事务
  4. Berkeley DB中并没有数据库服务器的概念,它的程序库直接链接到应用程序中
  5. eXtremeDB是内存数据库,运行效率高

4,SQLite基础

  1. SQLite的源代码是C,其源代码完全开放。SQLite第一个Alpha版本诞生于2000年5月。 他是一个轻量级的嵌入式数据库。
  2. SQLite有以下特性:
    ·零配置一无需安装和管理配置;
    ·储存在单一磁盘文件中的一个完整的数据库;
    ·数据库文件可以在不同字节顺序的机器间自由共享;
    ·支持数据库大小至2TB;
    ·足够小,全部源码大致3万行c代码,250KB;
    ·比目前流行的大多数数据库对数据的操作要快;

5,sqlite3数据库的安装

  1. 本地安装:
    ·三个文件:
    libsqlite3-0_3.7.2-1ubuntu0.1_i386.deb
    sqlite3_3.7.2-1ubuntu0.1_i386.deb
    libsqlite3-dev_3.7.2-1ubuntu0.1_i386.deb
linux@linux:~/test/sqlite$ sudo dpkg -i *.deb
  1. 在线安装
linux@linux:~/test/sqlite$ sudo apt-get install sqlite3
  1. 在终端输入sqlite3,出现如下信息,表示安装成功
linux@linux:~/test/sqlite$ sqlite3
SQLite version 3.7.2
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> 

sqlite> .quite//退出

6,创建数据库

  1. 手工创建
    ·使用SQLite3工具,通过手工输入SQL命令行完成数据库创建.
    ·用户在Linux的命令行界面中输入SQLite3可启动SQLite3工具
  2. 代码创建
    ·在代码中常动态创建数据库
    ·在程序运行过程中,当需要进行数据库操作时,应用程序会首先尝试打开数据库,此时如果数据库并不存在,程序则会自动建立数据库,然后再打开数据库

7,SQLite基本命令

7.1,系统命令 , 都以’.'开头

     .help 	//帮助(显示所有命令)
     .exit 		//退出
     .quit		//退出
     .table   	//查看当前数据库下所有表
     .schema  	//查看表的结构

7.1.1,打开(创建)一个sqlite3数据库文件

  1. 在终端下运行sqlite3 <*.db>,出现如下提示符
    ·SQLite version 3.7.2
    ·Enter “.help” for instructions
    ·Enter SQL statements terminated with a “;”
    ·sqlite>
  2. <*.db> 是要打开的数据库文件。若该文件不存在,则自动创建
linux@linux:~/test/sqlite$ sqlite3 student.db
SQLite version 3.7.2
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> 
sqlite> .schema
CREATE TABLE stu(id integer,name char,socre integer);
sqlite> .schema stu
CREATE TABLE stu(id integer,name char,socre integer);
sqlite> 

7.2,SQL命令,不以".“开头,但以”;"结束

7.2.1,创建新表

sqlite>create table <table_name> (f1 type1, f2 type2,…);

  1. <table_name> 是表名
  2. f1、f2是字段,type1、type2是字段类型
  3. 字段与字段之间以“,”隔开
sqlite> create table stu(id integer,name char,socre integer);
sqlite> 

7.2.2,向表中添加新记录

sqlite>insert into <table_name> values (value1, value2,…);

sqlite> insert into stu values(1001,'zhangsan',88);
sqlite> insert into stu values(1002,"lisi",88);
sqlite> insert into stu values(1002,"王五",88);
sqlite> insert into stu values(1002,'赵六',88);
sqlite> 
  • 添加一条记录的部分字段
sqlite> insert into stu (name,score)values('王五',96);
sqlite> select *from stu;
1001|zhangsan|76
1002|lisi|86
|王五|96
sqlite> 

7.2.3,查询表中记录

  • sqlite>select * from <table_name>; //查询所有字段
sqlite> select * from stu;
1001|zhangsan|88
1002|lisi|88
1002|王五|88
1002|赵六|88
sqlite> 
  • select name,score from <table_name>; //查询指定的字段
sqlite> select name from stu;
zhangsan
lisi
王五
sqlite> 
  • sqlite>select * from <table_name> where < expression> ; //按条件查询数据库中的内容

select * from <table_name> where score = 80;
select * from <table_name> where score = 80 and name= ‘zhangsan’;
select * from <table_name> where score = 80 or name=‘wangwu’;
select * from <table_name> where score >= 85 and score < 90;

sqlite> select * from stu where score=76;
1001|zhangsan|76
sqlite> 

7.2.4,按指定条件删除表中记录

  • sqlite> delete from <table_name> where id=1003 and name=‘zhangsan’;
    不加where会删除整张表
sqlite> select *from stu;
1001|zhangsan|76
1002|lisi|86
|王五|96
sqlite> delete from stu where id=1002;
sqlite> select *from stu;
1001|zhangsan|76
|王五|96
sqlite> 

7.2.5,更新表中记录(修改)

  • sqlite>update <table_name> set <f1=value1>, <f2=value2>… where < expression>;
sqlite> select *from stu;
1001|zhangsan|76
|王五|96
sqlite> update stu set id=1002 where name='王五';
sqlite> select * from stu;
1001|zhangsan|76
1002|王五|96
sqlite> 

7.2.6, 在表中添加字段

  • sqlite>alter table <table_name> add column default …;
sqlite> alter table stu add column address char;
sqlite> select * from stu;
1001|zhangsan|76|
1002|王五|96|
sqlite> .schema
CREATE TABLE stu(id integer,name char,score integer, address char);
sqlite> update stu set address= "beijing";
sqlite> select * from stu;
1001|zhangsan|76|beijing
1002|王五|96|beijing
sqlite> 

7.2.7,在表中删除字段

  • Sqlite3中不允许删除字段,可以通过下面步骤达到同样的效果
步骤 操作
创建一张新表,并从原表中提取字段 sqlite> create table stu as select id, name, score from student
删除原表 sqlite> drop table student
将新表名字改为原表 sqlite> alter table stu rename to student
sqlite> select * from stu;
1001|zhangsan|76|beijing
1002|王五|96|beijing
sqlite> create table stu1 as select id,name,score from stu;
sqlite> .table
stu   stu1
sqlite> drop table stu;
sqlite> .table
stu1
sqlite> alter table stu1 rename to stu;
sqlite> .table
stu
sqlite> select * from stu;
1001|zhangsan|76
1002|王五|96
sqlite> 

7.2.8,删除表

  • sqlite>drop table <table_name>

7.3,Sqlite中判断表是否存在的方法

sqlite会自动维护一个系统表sqlite_master,该表存储了我们所创建的各个table, view, trigger等等信息。

sqlite_master表数据字段:

type:  类型,取值一般为table, view
name:    
tbl_name:   表名
rootpage:
sql:创建表或者视图的sql语句,可以从该sql语句中判断某字段是否存在

sqlite_master表结构如下:

CREATE TABLE sqlite_master (   
type TEXT,   
name TEXT,   
tbl_name TEXT,   
rootpage INTEGER,   
sql TEXT   
); 

7.3.1,查看这个内建表的所有记录:

select * from sqlite_master

7.3.2,查询sqlite中所有表

select name from sqlite_master where type=‘table’ order by name;

7.3.3,查询sqlite中指定表

select * from sqlite_master where type = ‘table’ and name = ‘t_cmpt_cp’

8,SQLite编程接口

8.1,打开(或创建)sqlite数据库 sqlite3_open()

int sqlite3_open(char *path, sqlite3 **db);

  1. path:数据库文件路径
  2. db:指向sqlite句柄的指针(数据库的操作句柄)
  3. 返回值:成功返回0(SQLITE_OK),失败返回错误码(非零值)。If the database is opened (and/or created) successfully, then SQLITE_OK is returned. Otherwise an error code is returned.
int sqlite3_open(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb          /* OUT: SQLite db handle */
);
int sqlite3_open_v2(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb,         /* OUT: SQLite db handle */
  int flags,              /* Flags */
  const char *zVfs        /* Name of VFS module to use */
);

8.2,关闭sqlite数据库 sqlite3_close()

int sqlite3_close(sqlite3 *db);

返回值:成功返回0,失败返回错误码

8.3,返回错误信息 sqlite3_errmg()

const char *sqlite3_errmg(sqlite3 *db);
返回值:返回错误信息

8.4,执行SQL操作 sqlite3_exec()

Int sqlite3_exec(sqlite3 *db, const char *sql, sqlite3_callback callback, void *, char **errmsg);

  1. db:数据库(操作)句柄
  2. sql:SQL语句
  3. callback:回调函数(只有sql为查询语句的时候,才会执行此语句)
  4. errmsg:错误信息指针的地址
  5. 返回值:成功返回0(SQLITE_OK),失败返回错误码
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 */
);

8.4.1 找到一条记录自动执行一次回调函数

typedef int (*sqlite3_callback)(void *para, int f_num, char **f_value, char **f_name);

  1. para:传递给回调函数的参数
  2. f_num:记录中包含的字段数目
  3. f_value:包含每个字段值的指针数组
  4. f_name:包含每个字段名称的指针数组
  5. 返回值:成功返回0,失败返回-1

8.5,不使用回调函数执行SQL语句(操作)

int sqlite3_get_table(sqlite3 *db, const char *sql, char ***resultp, int*nrow, int *ncolumn, char **errmsg);

  1. db:数据库句柄
  2. sql:SQL语句
  3. resultp:用来指向sql执行结果的指针
  4. nrow:满足条件的记录的数目
  5. ncolumn:每条记录包含的字段数目
  6. errmsg:错误信息指针的地址
  7. 返回值:成功返回0,失败返回错误码

9,示例

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

#define DATABASE "stu.db"
/* 如果定义了CALLBACK,查询时,就用回调函数 */
//#define CALLBACK   

void operate_table_cmd_menu()
{
	puts("/******************************************/");
	puts("*operate table cmd menu:");
	printf("*1:insert 2:delete 3:query 4:update 5:quite \n");
	puts("/******************************************/");
	printf("Please input cmd:");
}
void operate_table_type_menu(char *str)
{
	puts("/******************************************/");
	printf("*%s table by:\n",str);
	if(strncasecmp(str,"update",strlen("update")) == 0)
		printf("*1:id 2:name 3:score 4:don't %s \n",str);
	else
		printf("*1:id 2:name 3:score 4:all 5:don't %s \n",str);
	puts("/******************************************/");
	printf("Please input type:");
}

int do_insert_sqlite3(sqlite3 * db);
int do_delete_sqlite3(sqlite3 *db);
int do_query_sqlite3(sqlite3 * db);
int query_callback(void *para, int f_num, char **f_value, char **f_name);
int do_update_sqlite3(sqlite3 * db);
const char *get_update_handle(char * set_str);

int main(int argc, const char *argv[])
{
	sqlite3 * db;
	char *errmsg;
	int cmd;

	//打开sqlite3数据库
	if(sqlite3_open(DATABASE,&db) != SQLITE_OK)
	{
		printf("%s\n",sqlite3_errmsg(db));
		exit(-1);
	}
	else
	{
		printf("open %s success.\n",DATABASE);
	}

	//创建一张数据库的表格   将ID设为主键值,并设为自增字段(保证字段唯一性)
	if(sqlite3_exec(db, "create table stu(id INTEGER PRIMARY KEY AUTOINCREMENT,name char,score Integer);",NULL,NULL,&errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	else
	{
		printf("create or open table success.\n");
	}

	while(1)
	{
		operate_table_cmd_menu();
		while(scanf("%d",&cmd) == 0)
		{
			getchar();
			operate_table_cmd_menu();
		}
		getchar();

		switch(cmd)
		{
			case 1:
				do_insert_sqlite3(db);
				break;
			case 2:
				do_delete_sqlite3(db);
				break;
			case 3:
				do_query_sqlite3(db);
				break;
			case 4:
				do_update_sqlite3(db);
				break;
			case 5:
				sqlite3_close(db);
				exit(0);
			default:
				printf("Error cmd.\n");
		}
	
	}
	return 0;
}


int do_insert_sqlite3(sqlite3 * db)
{
//	int id;
	char name[32] = {};
	int score;
	char sql[128];
	char *errmsg;
	int newline_ok =0;
/*
	printf("input student id:");
	scanf("%d",&id);
	getchar();
*/
	printf("input student name:");
	scanf("%s",name);
	getchar();

	printf("input student score:");
	scanf("%d",&score);
	getchar();

	sprintf(sql,"insert into stu values(NULL,'%s',%d);",name,score);//自增字段的值传NULL

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK )
	{
		printf("%s\n",errmsg);
		return -1;
	}
	else
	{
		printf("insert: ");
		sprintf(sql,"select * from stu where id=%d;",(int)sqlite3_last_insert_rowid(db));
		sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
		printf("done\n");

		return 0;
	}
}



int do_delete_sqlite3(sqlite3 * db)
{
	int id;
	char name[32] = {};
	int score;
	char sql[128];
	char *errmsg;
	int type;
	int return_val=0;
	int newline_ok;
	char y_Y[5];


	operate_table_type_menu("delete");
	while(scanf("%d",&type) == 0)
	{
		getchar();
		operate_table_type_menu("delete");
	}
	getchar();

	switch(type)
	{
		case 1:
		{
			printf("input student id:");
			scanf("%d",&id);
			getchar();
			
			newline_ok = 1;
			printf("Sure you want to delete:\n");
			sprintf(sql,"select * from stu where id=%d;",id);
			sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
			printf("if you sure,Please input y|Y: ");
			scanf("%s",y_Y);


			if(strncasecmp(y_Y,"y",strlen("y")) == 0)
			{
				sprintf(sql,"delete from stu where id=%d;",id);

				if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK )
				{
					printf("%s\n",errmsg);
					return_val = -1;
				}
				else
				{
					printf("delete done.\n");
					return_val = 0;
				}
			}
			else
			{
				return_val = 0;
				goto _cancel;
			}
			break;
		}
		case 2:
		{
			printf("input student name:");
			scanf("%s",name);
			getchar();
			
			newline_ok = 1;
			printf("Sure you want to delete:\n");
			sprintf(sql,"select * from stu where name='%s';",name);
			sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
			printf("if you sure,Please input y|Y: ");
			scanf("%s",y_Y);


			if(strncasecmp(y_Y,"y",strlen("y")) == 0)
			{
				sprintf(sql,"delete from stu where name='%s';",name);

				if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK )
				{
					printf("%s\n",errmsg);
					return_val = -1;
				}
				else
				{
					printf("delete done.\n");
					return_val = 0;
				}
			}
			else
			{
				return_val = 0;
				goto _cancel;
			}
			break;
		}
		case 3:
		{
			printf("input student score:");
			scanf("%d",&score);
			getchar();
			
			newline_ok = 1;
			printf("Sure you want to delete:\n");
			sprintf(sql,"select * from stu where score=%d;",score);
			sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
			printf("if you sure,Please input y|Y: ");
			scanf("%s",y_Y);


			if(strncasecmp(y_Y,"y",strlen("y")) == 0)
			{
				sprintf(sql,"delete from stu where score=%d;",score);

				if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK )
				{
					printf("%s\n",errmsg);
					return_val = -1;
				}
				else
				{
					printf("delete done.\n");
					return_val = 0;
				}
			}
			else
			{
				return_val = 0;
				goto _cancel;
			}
			break;
		}
			case 4:
		{
			newline_ok = 1;
			printf("Sure you want to delete:\n");
			sprintf(sql,"select * from stu;");
			sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
			printf("if you sure,Please input y|Y: ");
			scanf("%s",y_Y);


			if(strncasecmp(y_Y,"y",strlen("y")) == 0)
			{
				sprintf(sql,"delete from stu;");

				if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK )
				{
					printf("%s\n",errmsg);
					return_val = -1;
				}
				else
				{
					printf("delete done.\n");
					return_val = 0;
				}
			}
			else
			{
				return_val = 0;
				goto _cancel;
			}
			break;
		}
		case 5:
		{
_cancel:
			printf("Delete cancelled.\n");
			break;
		}
		default:
			printf("Error type.\n");
	}
	return return_val;
}

int do_query_sqlite3(sqlite3 * db)
{
	int id;
	char name[32] = {};
	int score;
	char sql[128];
	char *errmsg;
	int return_val=0;
	int type;
	int newline_ok = 1;
	char **resultp;
	int nrow;
	int ncolumn;


	operate_table_type_menu("query");
	while(scanf("%d",&type) == 0)
	{
		getchar();
		operate_table_type_menu("query");
	}
	getchar();

	switch(type)
	{
		case 1:
		{
			printf("input student id:");
			scanf("%d",&id);
			getchar();
		
			sprintf(sql,"select * from stu where id=%d;",id);

			if(sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg) != SQLITE_OK )
			{
				printf("%s\n",errmsg);
				return_val = -1;
			}
			else
			{
				return_val = 0;
			}
			break;
		}
		case 2:
		{
			printf("input student name:");
			scanf("%s",name);
			getchar();

			sprintf(sql,"select * from stu where name='%s';",name);

			if(sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg) != SQLITE_OK )
			{
				printf("%s\n",errmsg);
				return_val = -1;
			}
			else
			{
				return_val = 0;
			}
			break;
		}
		case 3:
		{
			printf("input student score:");
			scanf("%d",&score);
			getchar();
		
			sprintf(sql,"select * from stu where score=%d;",score);

			if(sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg) != SQLITE_OK )
			{
				printf("%s\n",errmsg);
				return_val = -1;
			}
			else
			{
				return_val = 0;
			}
			break;
		}
		case 4:
		{
			sprintf(sql,"select * from stu;");
#ifdef CALLBACK   
			/* 使用回调函数查询表格记录 */
			if(sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg) != SQLITE_OK )
			{
				printf("%s\n",errmsg);
				return_val = -1;
			}
			else
			{
				return_val = 0;
			}
#else
			/* 不使用回调函数查询表格记录 */
			if(sqlite3_get_table(db,sql,&resultp,&nrow,&ncolumn,&errmsg) != SQLITE_OK)
			{
				printf("%s\n",errmsg);
				return_val = -1;
			}
			else
			{
				int i,j,index=0;
				for(i=0;i<nrow+1;i++)//nrow是满足条件的记录的数目,即有几行数据,不包括字段名称
				{
					for(j=0;j<ncolumn;j++)
					{
						printf("%-10s",resultp[index++]);
					}
					puts("");
				}
			}
#endif
			break;
		}
		case 5:
		{
			printf("Query cancelled.\n");
			break;
		}
		default:
			printf("Error type.\n");
	}
	return return_val;
}

int query_callback(void *para, int f_num, char **f_value, char **f_name)
{

	int i;
	for(i=0;i<f_num;i++)
	{
		printf("%-10s",f_value[i]);
	}
	if(*(int *)para == 1)
		puts("");
	return 0;
}
int do_update_sqlite3(sqlite3 * db)
{
	int id;
	char name[32] = {};
	int score;
	char set_str[64];
	char sql[128];
	char *errmsg;
	int type;
	int return_val=0;
	int newline_ok;
	char y_Y[5];


	operate_table_type_menu("update");
	while(scanf("%d",&type) == 0)
	{
		getchar();
		operate_table_type_menu("update");
	}
	getchar();

	switch(type)
	{
		case 1:
		{
			printf("input student id:");
			scanf("%d",&id);
			getchar();
			
			newline_ok = 1;
			printf("Sure you want to update:\n");
			sprintf(sql,"select * from stu where id=%d;",id);
			sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
			printf("if you sure,Please input y|Y: ");
			scanf("%s",y_Y);
			getchar();


			if(strncasecmp(y_Y,"y",strlen("y")) == 0)
			{
				if(strncasecmp(get_update_handle(set_str),"cancel",strlen("cancel")) == 0)
					goto _return;
				else
				{
					sprintf(sql,"update stu %s where id=%d;",set_str,id);
					if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
					{
						printf("%s\n",errmsg);
						return_val =-1;
					}
					else
					{
						newline_ok = 0;
						printf("update: ");
						sprintf(sql,"select * from stu where id=%d;",id);//此处是有问题的,update后,有可能原id已被更新过了
						sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
						printf("done\n");
					}
				}
			}
			else
			{
				goto _cancel;
			}
			break;
		}
		case 2:
		{
			printf("input student name:");
			scanf("%s",name);
			getchar();
				
			newline_ok = 1;
			printf("Sure you want to update:\n");
			sprintf(sql,"select * from stu where name='%s';",name);
			sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
			printf("if you sure,Please input y|Y: ");
			scanf("%s",y_Y);
			getchar();
			
		
			if(strncasecmp(y_Y,"y",strlen("y")) == 0)
			{
				if(strncasecmp(get_update_handle(set_str),"cancel",strlen("cancel")) == 0)
					goto _return;
				else
				{
					sprintf(sql,"update stu %s where name='%s';",set_str,name);
					if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
					{
						printf("%s\n",errmsg);
						return_val =-1;
					}
					else
					{
						newline_ok = 0;
						printf("update: ");
						sprintf(sql,"select * from stu where name='%s';",name);//此处是有问题的,update后,有可能原name已被更新过了
						sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
						printf("done\n");
					}
				}
			}
			else
			{
				goto _cancel;
			}
			break;
		}
		case 3:
		{
			printf("input student score:");
			scanf("%d",&score);
			getchar();
			
			newline_ok = 1;
			printf("Sure you want to update:\n");
			sprintf(sql,"select * from stu where score=%d;",score);
			sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
			printf("if you sure,Please input y|Y: ");
			scanf("%s",y_Y);
			getchar();


			if(strncasecmp(y_Y,"y",strlen("y")) == 0)
			{
				if(strncasecmp(get_update_handle(set_str),"cancel",strlen("cancel")) == 0)
					goto _return;
				else
				{
					sprintf(sql,"update stu %s where score=%d;",set_str,score);
					if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
					{
						printf("%s\n",errmsg);
						return_val =-1;
					}
					else
					{
						newline_ok = 0;
						printf("update: ");
						sprintf(sql,"select * from stu where score=%d;",score);//此处是有问题的,有可能update后,原score已被更新过了
						sqlite3_exec(db,sql,query_callback,&newline_ok,&errmsg);
						printf("done\n");
					}
				}
			}
			else
			{
				goto _cancel;
			}
			break;
		}
		case 4:
		{
_cancel:
			printf("update cancelled.\n");
			break;
		}
		default:
			printf("Error type.\n");
	}
_return:
	return return_val;
}

const char *get_update_handle(char * set_str)
{
	int columns;
	int id;
	char name[32] = {};
	int score;

	puts("/******************************************/");
	printf("*PLease sure the columns you want to update:\n");
	printf("*1:id 2:name 3:score 4:cancel update\n");
	puts("/******************************************/");
	printf("Please choose the columns:");
	scanf("%d",&columns);
	getchar();
	switch(columns)
	{
		case 1:
		{
			printf("input student id:");
			scanf("%d",&id);
			getchar();
		
			sprintf(set_str,"set id=%d",id);
			break;
		}
		case 2:
		{
			printf("input student name:");
			scanf("%s",name);
			getchar();

			sprintf(set_str,"set name='%s'",name);
			break;
		}
		case 3:
		{
			printf("input student score:");
			scanf("%d",&score);
			getchar();
			
			sprintf(set_str,"set score=%d",score);
			break;
		}
		case 4:
		{
			printf("cancel update.\n");
			sprintf(set_str,"cancel");
			break;
		}
		default:
			printf("Error columns.\n");
			sprintf(set_str,"cancel");
	}

	return set_str;
}

猜你喜欢

转载自blog.csdn.net/m0_37542524/article/details/84730008