1. SQL语句
关系型数据库 SQL语句都是通用的
用数据库的特点很明显,可以将数据保存在数据库文件中,可以永久保存,也可以使用数据库相关指令进行查看
1.建表语句(创建数据库文件时,不会创建数据表,需要我们手动创建)
CREATE TABLE 表名(字段名1 字段的类型1, ...,字段名n 字段的类型n);
字段类型:
整型 INT 或者 INTEGER
字符串 CHAR 或者 TEXT
CREATE TABLE IF NOT EXIST student(id INT, name TEXT, score INTEGER);
2.向表中插入数据
//注意,sql语句中出现的字符串要用 双引号 或者 单引号 引起来
INSERT INTO student VALUES(1001, "张三", 98);
//这种插入方式 要求必须从左到右给表的每个字段都赋值
INSERT INTO student(id, name) VALUES(1002,"李四");
//这种方式可以给指定的字段插入数据
3.查询表中的记录
SELECT * FROM student; // * 表示查询所有字段
SELECT id,score FROM student;//表示只查询 id 和 score 字段
SELECT * FROM student WHERE score=96;//查询成绩是96的记录的所有字段
SELECT * FROM student WHERE name="赵六";//查询名字是 赵六 的记录的所有字段
//字符串要加单引号或者双引号
SELECT * FROM student WHERE name="赵六" AND score=90;
SELECT * FROM student WHERE score=98 OR score=96;
//可以使用AND或者OR连接多个条件 AND 并且 OR 或者
//也可以将查询的结果排序
SELECT * FROM student ORDER BY score DESC;
//ORDER BY 表示根据那个字段排序
//ASC 升序 DESC 降序 默认的是升序
4.修改表中的记录
//将表中成绩为 1003 的记录score字段的值修改成60
UPDATE student SET score=60 WHERE id=1003;
//即使条件不成立 也能执行成功 只不过没有任何事情发生
UPDATE student SET score=60,name="小红" WHERE id=1003;
5.删除表中的记录
//在表中删除 name 为张三的记录
DELETE FROM student WHERE name='张三';
//即使条件不成立 也能执行成功 只不过没有任何事情发生
//在表中删除 name 为张三的 或者 score为60 的记录
DELETE FROM student WHERE name="赵六" OR score=60;
6.删除数据表
DROP TABLE 表名;
7.添加一列
ALTER TABLE student ADD COLUMN sex CHAR;
8.删除一列
sqlite3 不允许直接删除一列
1)先创建一张新表
create table temp as select id , name from student;
2)删除原来的旧表
drop table student;
3)对新表重命名
alter table temp rename to student;
9.数据库主键(设置的数据将会是唯一存在的,每张表只有一个)
CREATE TABLE student(id INT PRIMARY KEY, name TEXT, score INTEGER);
2. 学生管理系统代码详情
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#define DATABASE "stu_manage.db"
//进程初始化的函数
int proc_init(sqlite3** my_db)
{
//打开数据文件
int ret = 0;
char* errmsg = NULL;
if (SQLITE_OK != (ret = sqlite3_open(DATABASE, my_db))) {
printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
__FILE__, __LINE__, ret, sqlite3_errmsg(*my_db));
exit(-1);
}
printf("数据库文件打开成功..\n");
//尝试创建数据表
//代码中sql语句可以不写分号
// IF NOT EXISTS 表示 如果不存在则创建 如果存在 则直接打开而不是报错
char sqlstr[256] = "CREATE TABLE IF NOT EXISTS student(id INT PRIMARY KEY, name CHAR, score INT)";
if (SQLITE_OK != (ret = sqlite3_exec(*my_db, sqlstr, NULL, NULL, &errmsg))) {
printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
__FILE__, __LINE__, ret, errmsg);
exit(-1);
}
printf("数据表打开成功..\n");
//释放errmsg
sqlite3_free(errmsg);
return 0;
}
//添加学员信息的函数
void insert_student(sqlite3* my_db)
{
int input_id = 0;
char input_name[32] = { 0 };
int input_score = 0;
printf("请输入新学员的id(INT):");
scanf("%d", &input_id);
printf("请输入新学员的name(CHAR):");
scanf("%s", input_name);
printf("请输入新学员的score(INT):");
scanf("%d", &input_score);
//组装sql语句
int ret = 0;
char sqlstr[256] = { 0 };
//在字符串的sql语句中再想使用引号时 使用单引号即可
sprintf(sqlstr, "INSERT INTO student VALUES(%d, '%s', %d)", input_id, input_name, input_score);
//调试数据库代码时 第一件事儿 先把要执行的sql语句打印出来
// printf("yangfs sql:[%s]\n", sqlstr);
//执行sql语句
if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, NULL, NULL, NULL))) {
printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
__FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
exit(-1);
}
printf("新学员信息插入成功..\n");
}
//修改学员信息的函数
void modify_student(sqlite3* my_db)
{
int modify_id = 0;
char modify_name[32] = { 0 };
int modify_score = 0;
printf("请输入要修改学员的id(INT):");
scanf("%d", &modify_id);
printf("请输入新的学员的name(CHAR):");
scanf("%s", modify_name);
printf("请输入新的学员的score(INT):");
scanf("%d", &modify_score);
int ret = 0;
char sqlstr[256] = { 0 };
//组装sql语句
sprintf(sqlstr, "UPDATE student SET name='%s',score=%d WHERE id=%d\n", modify_name, modify_score, modify_id);
printf("modify:sql [%s]\n", sqlstr);
// 执行sql语句
if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, NULL, NULL, NULL))) {
printf("文件%s的第%d行出错,错误码[%d],错误信息[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
exit(-1);
}
printf("学员信息修改成功...\n");
}
//删除学员信息的函数
void delete_student(sqlite3* my_db)
{
int delete_id = 0;
printf("请输入要删除学员的id(INT):");
scanf("%d", &delete_id);
int ret = 0;
char sqlstr[256] = { 0 };
//组装sql语句
sprintf(sqlstr, "DELETE FROM student WHERE id=%d\n", delete_id);
//关于数据库的操作 出错首先检查sql语句的输出
printf("delete:sql [%s]\n", sqlstr);
if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, NULL, NULL, NULL))) {
printf("文件%s的第%d行出错,错误码[%d],错误信息[%s]\n", __FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
exit(-1);
}
printf("学员删除成功...\n");
}
int flag = 0; //控制打印表头信息的标志位 0需要打印 1不需要打印
// 回调函数
int callback(void* arg, int ncolum, char** f_value, char** f_name)
{
putchar(10);
int i = 0;
//先打印表头
if (0 == flag) {
for (i = 0; i < ncolum; i++) {
printf("%10s", f_name[i]);
flag = 1;
}
putchar(10);
}
//再打印字段的值
for (i = 0; i < ncolum; i++) {
printf("%10s", f_value[i]);
}
putchar(10);
// 回调函数不加 return 会出现 错误 query aborted
return 0;
}
//查询学员信息的函数---基于回调函数实现
void search_student_callback(sqlite3* my_db)
{
//组装sql语句
int ret = 0;
char sqlstr[256] = { 0 };
sprintf(sqlstr, "SELECT * FROM student");
// 执行sql语句
if (SQLITE_OK != (ret = sqlite3_exec(my_db, sqlstr, callback, NULL, NULL))) {
printf("文件%s的第%d行出错,错误码[%d],错误信息[%s]\n",
__FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
exit(-1);
}
flag = 0; //重置打印表头的标志位置
printf("学员信息查询成功...\n");
}
//查询学员信息的函数---基于sqlite3_get_table实现
void search_student_sqlite3_get_table(sqlite3* my_db)
{
puts("");
char** result = NULL; //储存查询结果
int nrow = 0; //行数
int ncolumn = 0; //列数
int ret = 0;
char sqlstr[256] = { 0 };
// 组装sql语句
sprintf(sqlstr, "SELECT * FROM student");
if (SQLITE_OK != (ret = sqlite3_get_table(my_db, sqlstr, &result, &nrow, &ncolumn, NULL))) {
printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
__FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
exit(-1);
}
//先打印表头
int i = 0;
int j = 0;
for (i = 0; i < ncolumn; i++) {
printf("%10s", result[i]);
}
puts("");
//再打印内容
int index = i;
for (i = 0; i < nrow; i++) {
for (j = 0; j < ncolumn; j++) {
printf("%10s", result[index++]);
}
puts("");
}
// 释放sqlite3_get_table产生的结果集
sqlite3_free_table(result);
printf("学员信息查询成功..\n");
}
//打印菜单的函数
void print_menu()
{
printf("------------------------------------------\n");
printf("| 1.添加 2.修改 3.删除 4.查询 5.退出 |\n");
printf("-------------------------------------------\n");
printf("please input your choose : ");
}
int main()
{
sqlite3* my_db = NULL;
proc_init(&my_db);
int choose = 0;
while (1) {
print_menu();
scanf("%d", &choose);
switch (choose) {
case 1:
insert_student(my_db);
break;
case 2:
modify_student(my_db);
break;
case 3:
delete_student(my_db);
break;
case 4:
// search_student_callback(my_db);
search_student_sqlite3_get_table(my_db);
break;
case 5:
printf("期待您的再次使用...\n");
break;
}
if (5 == choose) {
break;
}
}
//关闭数据库句柄
sqlite3_close(my_db);
return 0;
}
程序测试图:
其中查询功能使用了两种方法:
1.callback回调函数–会根据sql语句查询到的结果 有几次结果就调用几次
// 回调函数
int callback(void* arg, int ncolum, char** f_value, char** f_name)
{
putchar(10);
int i = 0;
//先打印表头
if (0 == flag) {
for (i = 0; i < ncolum; i++) {
printf("%10s", f_name[i]);
flag = 1;
}
putchar(10);
}
//再打印字段的值
for (i = 0; i < ncolum; i++) {
printf("%10s", f_value[i]);
}
putchar(10);
// 回调函数不加 return 会出现 错误 query aborted
return 0;
}
2.sqlite3_get_table 函数
这种方法需要调用sqlite3_free_table()释放结果集–
void search_student_sqlite3_get_table(sqlite3* my_db)
{
puts("");
char** result = NULL; //储存查询结果
int nrow = 0; //行数
int ncolumn = 0; //列数
int ret = 0;
char sqlstr[256] = { 0 };
// 组装sql语句
sprintf(sqlstr, "SELECT * FROM student");
if (SQLITE_OK != (ret = sqlite3_get_table(my_db, sqlstr, &result, &nrow, &ncolumn, NULL))) {
printf("文件 %s 的第 %d 行出错,错误码[%d],错误信息[%s]\n",
__FILE__, __LINE__, ret, sqlite3_errmsg(my_db));
exit(-1);
}
//先打印表头
int i = 0;
int j = 0;
for (i = 0; i < ncolumn; i++) {
printf("%10s", result[i]);
}
puts("");
//再打印内容
int index = i;
for (i = 0; i < nrow; i++) {
for (j = 0; j < ncolumn; j++) {
printf("%10s", result[index++]);
}
puts("");
}
// 释放sqlite3_get_table产生的结果集
sqlite3_free_table(result);
printf("学员信息查询成功..\n");
}