7.2 网络编程_sql
数据库简介
常用的数据库
大型数据库 :Oracle
中型数据库 :Server是微软开发的数据库产品,主要支持windows平台
小型数据库 : mySQL是一个小型关系型数据库管理系统。开放源码 (嵌入式不需要存储太多数据)
SQLite基础
SQLite的源代码是C,其源代码完全开放。它是一个轻量级的嵌入式数据库。
SQLite有以下特性:
零配置一无需安装和管理配置;
储存在单一磁盘文件中的一个完整的数据库;
数据库文件可以在不同字节顺序的机器间自由共享;
支持数据库大小至2TB(1024G = 1TB); 嵌入式足够
足够小,全部源码大致3万行c代码,250KB;
比目前流行的大多数数据库对数据的操作要快;
创建SQLite数据库:
1. 手工创建
使用sqlite3工具,通过手工输入SQL命令行完成数据库创建.
-----------------两种方式都会用得到,重点是代码创建------------
--------2. 代码创建
在代码中常动态创建数据库 在程序运行过程中,当需要进行数据库操作时,应用程序会首先尝试打开数据库,
此时如果数据库并不存在,程序则会自动建立数据库,然后再打开数据库
虚拟中sqlite3安装
源码安装:
安装完成后,可以使用sqlite3 -version命令来测试是否安装成功
基础SQL语句使用
sql有两种命令:
1. sqlite3系统命令 --- .开头
2. SQL命令 --- ;结尾
命令在 记事本 中详细展示, 群内已分享 sqlite3 sql语句.txt
sqlite3 API接口
https://www.sqlite.org/c3ref/funclist.html
常用接口会在 sqlite3 编程中具体展示
sqlite3的使用:
1.使用sql系统命令, 创建(或打开)一个学生库; //如果库不存在,则为创建, 否则为打开
2.使用SQL命令 , 创建表;
- 使用SQL命令 , 插入内容;
4.使用 SQL命令 , 查询内容
5.使用SQK命令 , 设置主键
6.删除一个表
7.打开图形化数据库
sqlite3编程
头文件: #include <sqlite3.h>
编译方式: gcc 文件名.c -lsqlite3
打开或创建数据库
打开或创建数据库
sqlite3_open
头文件: #include<sqlite3.h>
声明: int sqlite3_open(char *path, sqlite3 **db);
功能:打开sqlite数据库 (或新建数据库)
参数:
path: 数据库文件路径
db: 指向数据库句柄的指针
- 该二级指针指向一级指针地址,最终会存储打开的数据库的首地址
返回值:成功返回0,失败返回错误码(非零值)
使用: sqlite3 *db;
if(sqlite3_open("stu.db",&db) != 0)
{
fprintf(stderr,”err: %s\n”,sqlite3_errmsg(db));
}//sqlite3自带的打印错误信息
打印错误信息
打印错误信息
sqlite3_errmsg
声明:const char *sqlite3_errmsg(sqlite3 *db); //bd;
功能: 打印错误信息
返回值:返回错误信息
使用: fprintf(stderr,"sqlite3_open failed %s\n",sqlite3_errmsg(db));
关闭数据库
sqlite3_close
声明: int sqlite3_close(sqlite3 *db);
功能:关闭sqlite数据库
返回值:成功返回0,失败返回错误码
使用: sqlite3_close(db);
执行sql语句
功能:执行sql语句;
原型:
int sqlite3_exec(
sqlite3 *db, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**),
void *arg, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
参数:
sqlite3 *db:指定要操作的数据库句柄指针;
char *sql:指定要执行的sql语句;
int (*callback)(void*,int,char**,char**):回调函数;
void *arg:传递给回调函数的第一个参数;
- 类似线程函数传参,需强转 - 不传参可以填NULL
char **errmsg:该二级指针指向的以一级指针会存储错误信息的首地址;
(定义一个一级指针就好了)
错误信息存储在静态存储区,存在着相应的源码,我们不用去深究
返回值:
成功,返回SQLITE_OK,其实就是0;
失败,返回
rror_code,其实就是非0
使用回调函数的条件: 需要终端打印出内容的时候 select: 查询
sqlite3_exec : 每查询到一行满足条件的信息, 都会调用一次callback函数显示结果
int sqlite3_exec 的回调函数:(一般在执行 需要终端打印数据的时候使用)
int callback(void *arg, int columns, char **column_text, \
char **column_name);
功能:sqlite3_exec每找到一条满足条件的记录,就会执行一次回调函数。
参数:
void *arg:sqlite3_exec的第四个参数传入;
int columns:查询结果的列数;
char **column_text:该二级指针指向的是一个数组,该数组是一个指针数组
数组中的元素都是char*类型的指针。指针指向查询结果的内容
char **column_name:该二级指针指向的是一个数组,该数组是一个指针数组
数组中的元素都是char*类型的指针,指针指向查询结果的列名;
返回值
:
成功时候必须返回0,该返回值会返回给sqlite3_exec函数,
如果没有返回0,则sqlite3_exec会认为回调函数运行失败,从而导致sqlite3_exec运行失败; //记得加入 return 0;
二级指针:
注意(exec_callback机制):
- exec的查询 是按照一行一行查询的, 第一行, 调用callback, callback运行完毕return 0;
然后查询第二行, 再调用 callback, callback 运行完毕, return 0;
查询第三行 …
2.exec 每行查询到的内容, 都会存在一个指针数组内, 所以每行指针数组内容的数据都不一样
#include <stdio.h>
#include <sqlite3.h>
int select_callback(void *arg,int lie,char **text,char **name);
int flag;
int main(int argc, char const *argv[])
{
//1.打开或创建数据库
sqlite3 *db = NULL; //防止野指针
if(sqlite3_open("./my.db",&db) != 0)
{
//不能用perror, perror只能打印操作系统级别的错误 sqlite是独立的
//fprintf代表 格式化输出到流内
fprintf(stderr,"sqlite_open is err: %s\n",sqlite3_errmsg(db));
//printf("sqlite3_open is err: %s\n",sqlite3_errmsg(db);
return -1;
}
printf("create is success\n");
//2.创建表
char *errmsg = NULL;
if(sqlite3_exec(db,"create table stu(id int,name char,score float);",\
NULL,NULL,&errmsg) != SQLITE_OK)
{
fprintf(stderr,"create table is err: %s\n",errmsg);
}
printf("table is success\n");
//3.向表内插入内容
int num,id;
char name[32];
char sql[128];
float score;
//提示 输入要插入的个数
printf("please input your number\n");
scanf("%d",&num);
for(int i = 0; i < num; i++)
{
scanf("%d %s %f",&id,name,&score);
sprintf(sql,"insert into stu values(%d,\"%s\",%f);",id,name,score);
if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
{
fprintf(stderr,"create table is err: %s\n",errmsg);
return -1;
}
}
flag= 1;
//4.查询表内的内容 查询内容需在终端打印出查询到的结果,这个时候需要使用callback
if(sqlite3_exec(db,"select * from stu;",select_callback,NULL,&errmsg)!= SQLITE_OK)
{
fprintf(stderr,"select is err: %s\n",errmsg);
return -1;
}
sqlite3_close(db);
return 0;
}
//callback的查找,在库中,是一行一行查找,查找完一行, 退出return0
// 退出后, 重新回到sqlite3_exec,再次调用callback,查找第二行 .....一直到查询完所有的行数
int select_callback(void *arg,int lie,char **text,char **name)
{
//满足条件的列数
//printf("%d\n",lie);
if(flag == 1)
{
for(int i = 0; i < lie; i++)
{
//二级指针 指向存储查询结果的指针数组, 通过二级指针,访问指针数组的内容
printf("%s\t",name[i]); //id name score
flag = 0;
}
printf("\n");
}
//for循环不能超过满足的列数
for(int i = 0; i < lie; i++)
{
//二级指针 指向存储查询结果的指针数组, 通过二级指针,访问指针数组的内容
printf("%s\t",text[i]); //text[0]
}
printf("\n");
return 0;
}
sqlite3_get_table()查询函数
只用于查询 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:该一级指针指向的内存空间中存储结果的行数,(一级指针指向变量地址)
包括列名 id name sorce
ncolumn:该一级指针指向的内存空间中存储结果的列数
errmsg:该二级指针指向的一级指针会存储错误信息首地址返回值:成功返回SQLITE_OK,失败返回错误码