1,数据库基本概念:数据(Data)、数据库 (Database)
2,常用的数据库
关系型数据库是在建立表格的时候, 数据与数据之间是依靠逻辑关系建立起来数据的存储关系
3,基于嵌入式的数据库
4,SQLite基础
5,sqlite3数据库的安装
linux@linux:~/test/sqlite$ sudo dpkg -i *.deb
linux@linux:~/test/sqlite$ sudo apt-get install 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,创建数据库
7,SQLite基本命令
7.1,系统命令 , 都以’.'开头
.help //帮助(显示所有命令)
.exit //退出
.quit //退出
.table //查看当前数据库下所有表
.schema //查看表的结构
7.1.1,打开(创建)一个sqlite3数据库文件
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
sqlite> create table stu(id integer,name char,socre integer);
sqlite>
7.2.2,向表中添加新记录
sqlite>insert into
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 stu;
1001|zhangsan|88
1002|lisi|88
1002|王五|88
1002|赵六|88
sqlite>
sqlite> select name from stu;
zhangsan
lisi
王五
sqlite>
select * from
select * from
select * from
select * from
sqlite> select * from stu where score=76;
1001|zhangsan|76
sqlite>
7.2.4,按指定条件删除表中记录
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> 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 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,在表中删除字段
步骤 | 操作 |
---|---|
创建一张新表,并从原表中提取字段 | 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,删除表
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);
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);
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);
8.5,不使用回调函数执行SQL语句(操作)
int sqlite3_get_table(sqlite3 *db, const char *sql, char ***resultp, int*nrow, int *ncolumn, char **errmsg);
9,示例
#include
#include
#include
#include
#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;
}