MySql笔记

mysql5.7版本在公司中主流使用

mariadb为mysql的分支free版本,在centos7中默认安装(mysql被oracle收购)

1.mysql初始

启动mysql:

systemctl start mysqld

连接mysql

无密码则直接用mysql命令连接

若有密码则用下列命令行

mysql -u 用户名 -p

此时会要求输入密码

 输入正确密码后可以看到连接成功

1.1客户端与服务端

mysql服务端:数据库管理软件

mysql客户端:程序员使用的和数据库服务交互的软件

linux命令行中使用的mysql指令为mysql的客户端,mysqld为服务端,通过mysql命令与服务端交互

服务端会有两个进程:mysqld与mysql_safe

mysql_safe:守护进程,守护mysqld,当mysqld挂掉时,快速拉起

1.2启动服务端

启动:systemctl start mysqld

关闭:systemctl stop mysqld

重启:systemctl restart mysqld

自启动:systemctl enable mysqld

开机不启动:systemctl disable mysqld

1.3连接mysql服务端

mysql -h [服务端所在地址] -P [端口号] -u [用户名] -p

在连接服务端(mysqld)时,mysqld会针对连接上来的客户端所在的ip进行校验,因此,上述命令中的u代表的是客户端(mysql)的用户名(非linux中的用户)

mysqld会先判断-u是否能够从地址为ip的机器进行登录,若可以则校验密码。

1.4mysql服务端、数据库、表的关系

mysql服务端是数据库管理软件

服务端(msyqld)可以管理多个数据库,是个进程

每个数据库中有多个表

数据库相当于文件夹,表相当于一个个文件

my.cnf为数据库的配置文件,在/etc中,datadir代表了数据库的位置路径:默认为/var/lib/mysql,这下面的每个文件夹代表一个数据库,其中的每个文件代表一个表

1.5mysql服务端分层认识

服务端可分为4层,自上至下分别为:连接层、服务层、存储引擎、磁盘。

连接层:

1.用于建立连接,跨网络,TCP;同一台机器则通过套接字AF_UNIX(进程间通信)

2.检验用户名和密码:连接服务端时,-u输入的是Mysql的一个用户,不是Linux的root用户

3.校验客户端ip地址:一般mysql默认创建的用户不支持跨网络连接

服务层

1.sql语法语义检测

2.优化sql

3.将sql交给存储引擎进行执行

存储引擎

1.执行sql

2.获取执行结果

3.结果返回给服务层

1.6建立数据库demo测试

创建数据库: create database 数据库名; 相当于创建文件夹

使用数据库:use 数据库名;

创建表:create table 表名(自定义名称 类型,....);若类型为varchar,需要给出有几个字符例如varchar(2)代表两个

插入数据:insert into 表名(自定义名称,....) values (值,...);如果值是字符串,需要用"  ' ' "包围

插入数据时,若带有中文,可能会报错(1366),此时可以更改数据库、表、字段的字符集

alter database mydb character set gbk;
alter table department character set gbk;
alter table department modify dname varchar(20) character set gbk;

查询数据:select * from 表名;查找某个表中的所有数据

 如该图所示,id、name、gender被称作表字段(列字段),其存储了字段名以及属性

表的下半部分为表数据,一行为一个表数据(表记录),逻辑存储时是行列存储

1.7sql语言分类

DDL(data definition language)数据定义语言,用于维护存储数据的结构,create,drop,alter

DML(data manipulation language)数据操纵语言,用于对数据进行操作,insert,delete,update

DCL(data control language)数据控制语言,负责权限管理与事务,grant,revoke,commit

2.数据库的操作

2.1创建数据库

create database 【数据库名】【字符集】【校对规则】;

字符集:charset

校对规则:collation

eg:

创建数据库时指定字符集

create database test3 charset utf8;

此时向其中创建一个student表,并插入带有中文的数据不会报错

2.2数据库字符集

系统默认的字符集可通过以下语句查看

show variables like 'character_set_database';

可通过以下语句查看系统支持的字符集

show charset;

字符集的选择决定了数据库能够存储的字符范围

2.3数据库校对规则

校对规则决定当前数据库是否大小写敏感,会对查询的排序有影响

后缀为_ci的不区分大小写,后缀为_bin的区分大小写

默认不敏感。

例如,若数据中有'a'和'A',则在查找'a'时,如果不敏感则会返回'a'与'A',否则只返回'a'

2.4操纵数据库

查看有多少数据库:

show databases;

查看某个数据如何创建:

show create database 数据库名;

修改数据库属性:

alter database [数据库名] [属性]=[新属性];

此时已经将数据库test3的字符集更改为utf8

删除数据库:

drop database [数据库名]

 2.5查看数据库连接状态

show processlist;

 2.6数据库备份

备份:
mysqldump -P3306 -u root -p[密码] -B 数据库名 > 数据库备份存储的文件路径
还原:
source 数据库备份存储的文件路径

2.7数据库表备份

备份:
mysqldump -P3306 -u root -p[密码] -B 数据库名 表名1 表名2 > 数据库表备份存储的文件路径
还原:
source 数据库备份存储的文件路径
若备份时没有-B参数,恢复时需要先建立空数据库,再用source来还原

3.表的操作

3.1表的创建

语法规则

create table 表名(
    自定义变量名1 类型,
    自定义变量名2 类型,
    自定义变量名3 类型,
)character set 字符集 collate 校验规则 engine 存储引擎;

字符集与校对规则不设置,默认采用数据库的字符集与校对规则

创建示例:

 desc + 表名可以查看表结构

Innodb的存储:.frm文件为表结构文件,.ibd文件为表数据文件

MyISAM的存储:.frm为表结构,MYD为表数据,MYI为表索引

以上可以在/etc/var/lib/mysql下的各个数据库文件下找到

3.2查看表

查看如何建表:show create table 表名称;

查看表结构desc 表名称;

3.2修改表

增加列

alter table 表名 add 列名 类型;

删除列
alter table 表名 drop 列名;

 慎用删除列,因为会将列数据全部删除

修改属性(类型)

alter table 表名 modify 列名 列属性
alter table 表名 change 列名 新列名 新类型;

 修改表名

alter table 表名 rename 新名称;

 修改列名

alter table 表名 change 列名 新列名 新属性;

 删除表

drop table 表名;

 插入数据

insert into 表名 (列名,列名,...) values(值,值,...);

 不加列名则values中需要给出每个列的对应值

4. 数据类型

4.1数据类型分类

4.1.1bit类型

bit(M):位字段类型,M代表每个值的位数,范围1-64,M默认为1

bit字段在显示时按照ascii码对应值进行显示

4.1.2浮点数类型:

float(M,D)占用4字节,M代表显示位数,D代表小数位数,精度保证6-7位

double(M,D)占用8字节,M代表显示位数,D代表小数位数,精度保证15-16位

decimal(M,D):M代表显示位数,D代表小数位数,理论上精度不会丢失,因为是按照字符串进行保存,但存储时,一定确定存储的小数和D的关系。M最大65,D最大30

eg:decimal(10,2)存入1.123,实际存储1.12

4.1.3字符串类型

char(size)固定长度字符串:固定长度字符串,size是能够存储的长度,单位为字符,最大长度值可为255.该方法容易造成空间浪费,当存储的字符串长度<size时,仍会按照size长度存储

varchar(size):可变长度字符串,size代表字符长度,最大长度65535个字节

size最大有多大

其中有1-3字节用于记录字符串多长,按最大情况算,剩余字节数量65532.

在utf8字符集中,每个字符占用字节数量为1-3字节,按照最大计算,65532/3=21844

char与varchar的比较:

 varchar占用字节中的“+1”是多了用于存储长度的字节

如何选择定长或变长字符串

若数据确定长度一样,则用定长,如身份证、手机号

若数据长度有变化,用变长,如名字、地址,但要保证最长的能够存储

定长的磁盘空间比较浪费,但效率高

变长的磁盘空间比较节省,但效率低

定长的意义:直接开辟好对应的空间

变长的意义:在不超过自定义范围的情况下,用多少开辟多少

4.1.4日期和时间类型

常用日期有三种:

date:日期'yyyy-mm-dd',占用3字节

datetime:日期时间格式'yyyy-mm-dd HH:ii:ss'表示范围从1000-9999,占8字节

timestamp:时间戳,从1970年的yyyy-mm-dd HH:ii:ss格式和datetime完全一致,占4字节

4.1.5枚举类型

enum('选项1','选项2','选项3',...):该设定提供了若干个选项的值,最终一个单元格中,实际只存储其中某一个值,必须是其中的某个值

4.1.6集合类型

set('选项值1','选项值2'...):该设定提供了若干个选项的值,最终一个单元格中,可存储其中任意多个值。

 4.1.7集合查询

find_in_set(sub,str_list)函数:若sub在str_list中,返回其下标,不在则返回0,str-list是用','分割的字符串

使用时前面加上select

 5.表的约束

表的约束指除了字段类型约束之外的额外约束

5.1空属性

null:可以为空

not null 不能为空

默认字段基本都是字段为空

在创建表时,通过对字段定义not null可令其不能为空

5.2默认值

default[val]

默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候, 用户可以选择性的使用默认值

5.3列描述

comment '描述'

对插入、查询没有影响,相当于注释

5.4zerofill格式化输出

设置了zerofill的字段会按照设定的宽度进行输出

例如int(5)在输出时会输入5位

5.5主键

约束列字段:primary key

不能为空、不能重复

一张表只有一个主键

主键列通常为整数(方便建立索引)

主键创建方式

(1).创建表时指定

直接在某个字段后指定:

create table 表名(字段1 字段1类型 primary key,...);

在所有字段后面指定:

create table 表名(字段1 字段1类型,字段2 字段2类型...., primary key(字段名称));

(2).alter修改表结构

alter table 表名 add primary key 列名;

 删除主键:

alter table 表名 drop primary key;

复合主键:
当表中的字段值有重复可能时,若还想创立主键,可用多个列建立复合主键,复合主键的列的值,在表当中唯一。

例如:若name列可能重复,class列可能重复,但name与class组合自来的值没有重复,则可以用Name,class作为负荷主键

create table 表名(字段1,字段1类型, 字段2 字段2类型, 字段3....,primary key(字段1名称,字段2名称));

5.6自增长

auto_increment:当对应字段,若不给值,则会自动被系统触发,系统会从当前字段中执行最大值+1操作

任何字段要自增长,前提是本身是个索引(key一栏有值)

自增长字段必须为整数

一张表最多只有一个自增长

5.7唯一键

一张表往往有多个字段需要唯一性,数据不能重复,但一张表只能有一个主键,因此引入唯一键。

可以解决表中有多个字段需要唯一性约束的问题

唯一键允许为空,可以多个为空,空字段不做唯一性比较

唯一键:unique

5.8外键

外键定义了表与表之间的关系

两个表从逻辑上区分为主表和从表

外键的约束定义在从表上

主表的字段需要为主键

从表定义的外键本质是通过主表的字段约束从表的外键列

外键定义:

foreign key 字段名 references 主表列;放在从表

当从表中有了外键约束后,在插入时,外键约束列必须是主表字段中的值

如:有物品和购买记录两个表,购买记录中的

insert into 表名(列名1, 列名2,...)values(列名1对应的值,列名2对应的值,...);

物品列必须是物品表中的物品列时,可以将二者用外键约束。其中物品表为主表,购买记录表为从表。

这样做之后若向购买记录表中插入某个物品的记录,会看这个物品是否在主表的物品列中出现,是才会继续插入,否则会报错。

6.基础查询(单表)

6.1创建表

create table 表名(列名1 列类型 [列约束], ...);

6.2单行插入

单行全列插入

insert into 表名 values(第一列的值,....);

单行指定列插入

insert into 表名(列名1,列名2,...) values(列名1对应值, 列名2对应值,...);

6.3多行插入

多行全列插入

insert into goods values(所有的值1),(所有的值2)...;

多行指定列插入

insert into goods(列名1,列名2) values(指定列的值1),(指定列的值2)...;

6.4替换

将表中某个数据替换成某个新的值

若主键或唯一键不冲突,则直接插入(有重复元素插入时,会删除之前的后再插入)

若主键或唯一键冲突,则删除后再插入

场景:有大量数据需要更新

replace into 表名 (指定列) values (指定列新的值);

 其中(指定列)省略时则是全列替换

6.5查询

6.5.1全表查询

表当中有多少记录就查询多少记录

select * from 表名;

*代表的是查询全列,没有where约束是默认查询全表数据

6.5.2全列查询
select * from 表名;
6.5.3指定列查询
select 列名1,列名2... from 表名;

6.5.4查询字段为表达式

 如下

6.5.5查询结果重命名
select customer_id, customer_id+10 结果 from customer;

6.5.6结果去重

select distinct ....

6.6指定行查询

where查询

6.6.1比较运算符

>,>=,<,<=:大于,大于等于,小于,小于等于

=:等于,NULL不安全,例如NULL=NULL的结果为NULL

<=>:等于,NULL安全,例如NULL<=>NULL的结果为TRUE(1)

!=,<>:不等于

BETWEEN a0 AND a1:范围匹配[a0,a1],若a0<=value<=a1,返回TRUE(1)

IN(option,...):若是option中任意一个,返回TRUE(1)

IS NULL:是NULL

IS NOT NULL:不是NULL

LIKE:模糊匹配。%代表任意多个字符(包括0个);_代表任意一个字符

6.6.2逻辑运算符

AND、OR、NOT

eg1:查询英语成绩小于60的同学:

select name, english from exam where english < 60;

 eg2:查询语文成绩在80-90之间的同学:

select name, chinese from exam where chinese >= 80 and chinese<=90;
select name, chinese from exam where chinese between 80 and 90;

eg3:查询数学成绩为58或59或98或99的同学

select name, math from exam where math=58 or math=59 or math=98 or math=99;
select name, math from exam where math in (58,59,98,99);

 eg4:查询姓孙的同学

select name from exam where name like '孙%';

 如果只想要“孙某”

select name from exam where name like '孙_';

 eg5:查询语文成绩好于英语的同学

select name, chinese, english from exam where chinese > english;

 eg6:查询总分在200以下的同学

select name, chinese+math+english from exam where chinese+math+english<200;

 eg7:查询语文成绩>80且不姓孙的同学

select name, chinese from exam where chinese>80 and name not like '孙%';

 eg8:要么为孙某同学,要么总成绩>200 且语文成绩<数学成绩且英语>80

select * from exam where (name like '孙_') or (chinese+math+english>200 and chinese < math and english>80);

6.7结果排序

order by [字段名称(不用加引号)] asc/desc:查询结果按照某个字段的值进行排序,asc代表升序,desc为降序,默认升序。

空比任何值都小

NULL比任何值都小

若有如下语句:

select name, math, english, chinese from exam order by math desc, english, chinese;

 则会先根据math进行降序,其中相同的math行的english会升序,相同math与english行的chinese会升序

按总分排序:

select name, chinese+math+english t_s from exam order by t_s;

 其中,t_s为总分的别名

注:order by中可以用别名,where中不可

6.8筛选分页结果

数据量过大时,可令其分页显示

下标从0开始

limit n;添加后令其输出n条

limit start, n;从start开始输出n条

limit n offset start;从start开始输出n条

6.9更新表

update 表名 set [字段]=[新的值] where [筛选条件];

 没有where则会更新所有行对应的列

eg:

update exam set math=100

该语句会经所有math改为100

update exam set math=100 where name like '孙%';

 找出所有姓孙的人,将其数学改为100.

6.10删除数据

delete from 表名 where 筛选条件

 删除数据之后,自增不会重置

6.11截断表

truncate table 表名

 直接将表数据全部删除,并重置表结构,当用delete删除数据后,自增不会重置,而经过截断之后则可以重新从1开始自增

注:

截断只对整表操作,不能向delete针对部分数据操作

当truncate在删除数据时,不经过真正的事务,因此无法回滚

其会重置AUTO_INCREMENT项

6.12聚合函数

6.12.1count

返回查询到的数据数量

select count(*) from exam;
6.12.2sum

返回查询的数据总和,不是数字没有意义

select max(math) from exam;

 查询exam表中math的最大值

6.12.3avg

返回查询数据的平局值

6.12.4max

返回最大值

6.12.5min

返回最小值

6.13分组查询

在select 中使用group by 子句可以指定列进行分组查询

select 列1,列2,... from 表名 group by 列名;

准备好雇员信息表(oracle 9i的经典测试表)

显示每个部门的平均工资与最高工资

group by 配合聚合函数进行分组查询

group by 配合having 进行分组过滤

注:

在使用group by 时遇到了报错:

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'scott.emp.empno' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

解决方法:

mysql中执行:

mysql> set global sql_mode=‘STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’;

mysql> set session sql_mode=‘STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’;

找出每个部门的工资最大值 :

找平均工资小于2000的部门

groupby 后可以用having进行分组过滤

 7.内置函数

7.1日期函数

current_date()当前日期

current_time()当前时间

current_timestamp()当前时间戳

date(datetime)返回datetime参数的日期部分

date_add(date,interval d_value_type)在date中添加日期或时间,interval后的数值单位可以是day

 date_sub(date, interval d_value_type)在date中减去日期或时间

datediff(date1,date2):两个日期的差,单位为天

now():当前日期时间

 7.2字符串

charset(set)返回字符串字符集

 concat(以','分割的字符)连接字符串

instr(str, sub):返回sub在str中出现的位置,没有则为0,下标从1开始

 ucase('')小写转大写

lcase('')大写转小写

left(str, n):从str左边开始取n个字符

 length(str):求str长度

replace(str, search, des):将str中的search替换为des

 strcmp(str1, str2):比较两个字符串大小

 substring (str, pos, [length]):从str的pos开始取length个字符

不添加length则取后续所有字符

 

eg:让emp表中ename的首字母小写:

7.3数学函数

 abs(n):取绝对值

bin(decimal_number)十进制转二进制

hex(n)转16进制

conv(n, from_base, to_base)进制转换

10从10进制转2进制

ceiling(n)向上取整

floor(n):向下取整

format(n, 小数位数):将n保留几位

rand()返回随机浮点数,范围[0, 1]

mod(n, d):求模,取余

 

7.4其他函数

user()查询当前用户(mysql的用户,而非linux用户)

 database()显示正在使用的数据库

password()进行加密,密码强度有要求,mysql数据库使用该函数对用户进行加密

 isnull(值1, 值2):判断值1是否为空,否则返回值2

8.复合查询

8.1多表查询

实际开发中数据来自不同表,需要多表查询

案例:显示雇员名、雇员工资以及所在部门的名字,以上数据来自两个表:emp与dept,需要联合查询

emp:

 dept:

 由于部门名字在dname中(dname),因此需要联合查询

 当采用如下语句查询时会产生笛卡尔集

select *from emp, dept;

 结果如下,会令每个雇员与每个部门进行结合,一共产生14*4=56个结果

而每个员工只可能有一个部门,所以必定有三个是不正确的,因此,对该结果还需要用where语句进行约束

select *from emp, dept where emp.deptno = dept.deptno;

 由于只需要雇员名、工资以及部门名,因此最终语句为:

select ename, sal, dname from emp, dept where emp.deptno = dept.deptno;

 8.2自连接

自连接指在同一张表连接查询

案例:显示员工ford的上级编号mgr和其对应的名字ename

 需要先找到上级编号mgr,然后用mgr重新在表中找empno=mgr的人就是领导

自连接方式寻找上级:

select l.ename, l.empno from emp l, emp w where w.mgr = l.empno;

该方法将两个相同的emp组成笛卡尔集,有14*14条记录

 会让emp l中的每个记录与emp w中的每个记录形成组合,因此有14*14条记录

此时可以将l看做领导,w看做下级,则约束就是w.mgr=l.empno(即w的上级编号和领导的编号一致)

题目要求获取FORD的上级,最后结果如下:

select l.ename, l.empno from emp l, emp w where w.mgr = l.empno and w.ename='FORD';

 子查询方法:

8.3子查询

8.3.1单行单列子查询

子查询的值为单行单列

eg:

8.3.2多行单列子查询

子查询的值为多行单列

in:

eg:找到与部门10工作岗位相同的雇员名、工资、编号

此处,子查询为一个多行单列的查询,会将编号为10的岗位显示出来

all:全部

eg:显示工资比部门30的所有员工的工资高的员工姓名

any:任意一个

eg:显示工资比30部门任意员工工资高的员工姓名、工资以及部门号包括自己部门

 8.3.3单行多列子查询

eg:查询与smith的部门与岗位完全相同的所有雇员,不含smith

smith的部门与岗位的查询为一个单行多列的结果

 此时用(列名)=子查询即可

8.3.4在from中使用子查询

即将子查询当做临时表使用

eg:显示每个高于自己部门平均工资的员工姓名、部门、工资、平均工资

 子查询为select deptno dep, avg(sal) a_s from emp group by deptno;即每个部门的编号以及平局工资

将这个查询结果同tmp组成一个笛卡尔集,要保证tmp编号和emp的部门编号相同

且tmp.a_s(平均工资)<emp.sal(雇员工资)

从中查询出ename、deptno、sal、a_s即可

8.4合并查询

union与union all

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行(union),若不希望去重则使用union all。

eg:查找工资高于2500的或岗位为MANAGER的所有人

union:

 union all:

9.内外连接

9.1内连接

结果仅包含符合连接条件的两表中的行

select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;

 实际是用where子句对两个表形成的笛卡尔集进行筛选

多表查询其实就是内连接

eg:显示smith的名字和部门名称

多表查询:

标准内连接写法:

9.2外连接

9.2.1左外连接
select 字段名 from 表1 left join 表2 on 连接条件;

 eg:

建立下表:

create table stu (id int, name varchar(30)); -- 学生表
insert into stu values(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
create table exam (id int, grade int); -- 成绩表
insert into exam values(1, 56),(2,76),(11, 8);

 如下两张表:

 要求查询姓名和考试成绩,若没有这个同学的成绩,也需要输出这个同学

9.2.2右外连接
select 字段 from 表1 right join 表2 on 连接条件;

eg:查询所有考试成绩,无论有无学生,必须展示所有成绩

10.附加内容

10.1判断语句

可用于update语句中:

if(表达式, 成立时的值,不成立时的值);

10.2程序中使用Mysql

#include<mysql/mysql.h>

编译时需要链接库:-lmysqlclient

且需要指定位置:-L /usr/lib64/mysql

初始化操作句柄
MYSQL *mysql_init(MYSQL *mysql)
连接mysql服务端
mysql_real_connect(
    MYSQL *mysql,//操作句柄
    const char *host,//服务端ip
    const char *user,//用户名
    const char *passwd,//密码
    const char *db,//数据库
    unsigned int port,//端口
    const char *unix_socket,//是否使用本地域套接字
    unsigned long client_flag//数据库标志位,通常为0,采用默认属性
)
连接mysql服务端,若成功,返回mysql操作句柄,失败返回NULL
#include<stdio.h>
#include<mysql/mysql.h>
#include<iostream>
using namespace std;
int main()
{
    //连接
    MYSQL sql;
    mysql_init(&sql);//初始化
    MYSQL *ret = mysql_real_connect(&sql, "43.139.111.234", "root","p@ssw0rd","ChatSystem", 3306, NULL, 0);
    if(ret==NULL){//连接失败
        cout<<"连接失败"<<endl;
        return 0;
    }
    cout<<"连接成功"<<endl;
    return 0;
}

#include<stdio.h>
#include<mysql/mysql.h>
#include<iostream>
using namespace std;
int main()
{
    //连接
    MYSQL sql;
    mysql_init(&sql);//初始化
    MYSQL *ret = mysql_real_connect(&sql, "43.139.111.234", "root","p@ssw0rd","ChatSystem", 3306, NULL, 0);
    if(ret==NULL){//连接失败
        cout<<"连接失败"<<endl;
        return 0;
    }
    cout<<"连接成功"<<endl;
    //设置连接的字符集
    mysql_set_character_set(&sql, "utf8");
    //执行sql语句
    //插入
    int n = mysql_query(&sql, "insert into user(userid, username, phone, passwd) values (1, 'lb', '18302919133', 'lb1421755462');");
    if(n==0){
        cout<<"1执行成功"<<endl;
    }
    n = mysql_query(&sql, "select * from user;");
    if(n==0){
        cout<<"2执行成功"<<endl;
    }
    //获取结果集
    MYSQL_RES *res = mysql_store_result(&sql);
    if(res==NULL){
        //获取失败
        cout<<"3执行失败"<<endl;
        return 0;
    }
    //获取结果集中的行数
    int nums = mysql_num_rows(res);
    cout<<nums<<endl;
    //遍历结果集,获取内容,按行获取
    for(int i=0;i<nums;i++){//res最开始指向第一行
        MYSQL_ROW row = mysql_fetch_row(res);//获取一行的信息   
        cout<<row[0]<<","<<row[1]<<","<<row[3]<<endl;//打印3列信息
    }
    //释放结果集
    mysql_free_result(res);
    //关闭连接
    mysql_close(&sql);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值