JavaSE大神进阶篇(第十一期):MySQL从安装到存储过程的保姆级通关秘籍(2026最新版)
·
数据库基本概念
数据库类型和常见的关系型数据库
-
【1】数据库类型
-
【2】常见的关系型数据库
MySQL介绍
MySQL8的安装
-
【1】MySQL的版本:
-
【2】官方下载地址:
-
【3】安装过程:
-
1.双击
MySQL安装文件mysql-installer-community-8.0.18.0.msi,出现安装类型选项 -
2.选择,然后继续:
-
3.进入产品配置向导,配置多个安装细节,点击Next按钮即可
-
4.高可靠性High Availability,采用默认选项即可
-
5.类型和网络 Type and Networking,采用默认选项即可。记住MySQL的监听端口默认是3306
-
6.身份验证方法Authentication Method,采用默认选项即可
-
7.账户和角色 Accounts and Roles。MySQL管理员账户名称是root,在此处指定root用户的密码。还可以在此处通过Add User按钮添加其他新账户,此处省略该操作
-
8.Windows服务:Windows Service
-
9.Apply Configuration:点击Execute按钮执行开始应用这些配置项
-
PS:如果配置出错,查看右侧的log,查看对应错误信息。 执行完成后,如下图所示。单击Finish完成安装,进入产品配置环节
-
10.产品配置Product Configuration到此结束:点击Next按钮
-
11.安装完成 Installation Complete。点击Finish按钮完成安装
-
查看MySQL的安装结果
-
安装了Windows Service:MySQL80,并且已经启动

-
安装了MySQL软件。安装位置为:
C:\Program Files\MySQL(MySQL文件下放的是软件的内容)
-
安装了MySQL数据文件夹,用来存放MySQL基础数据和以后新增的数据。安装位置为
C:\ProgramData\MySQL\MySQL Server 8.0
-
在MySQL数据文件夹中有MySQL的配置文件:
my.ini。它是MySQL数据库中使用的配置文件,修改这个文件可以达到更新配置的目的。以下几个配置项需要大家特别理解
MySQL登录,访问,退出操作
-
【1】登录
-
【2】访问数据库
-
【3】退出数据库
数据库的卸载
-
停止MySQL服务:在命令行模式下执行
net stop mysql或者在Windows服务窗口下停止服务
-
在控制面板中删除MySQL软件

-
删除软件文件夹:直接删除安装文件夹C:\Program Files\MySQL,其实此时该文件夹已经被删除或者剩下一个空文件夹
-
删除数据文件夹:直接删除文件夹C:\ProgramData\MySQL。此步不要忘记,否则会影响MySQL的再次安装
-
删除path环境变量中关于MySQL安装路径的配置
使用图形客户端navicat12连接MySQL

-
【1】认识Navicat
-
Navicat Premium
-
【2】安装navicat
SQL语言入门
-
背景
-
【1】SQL语言入门
-
【2】SQL语言分为五个部分:
DDL_DML_创建数据库表
-
【1】认识数据库表
-
【2】创建数据库表 t_student
-
(1)创建数据库:

-
(2)新建查询:

-
(3)创建数据库表:
##这是一个单行注释 /* 多行注释 多行注释 多行注释 */ /* 建立一张用来存储学生信息的表 字段包含学号、姓名、性别,年龄、入学日期、班级,email等信息 */ -- 创建数据库表 create table t_student ( sno int(6), -- 6显示长度 sname varchar(5), --5个字符 sex char(1), age int(3), enterdate date, classname varchar(10), email varchar(15) ); -- 查看表的结构:展示表的字段详细信息 desc t_student; -- 查看表中数据: select * from t_student; -- 查看建表语句: show create table t_student; /* CREATE TABLE `t_student` ( `sno` int DEFAULT NULL, `sname` varchar(5) DEFAULT NULL, `sex` char(1) DEFAULT NULL, `age` int DEFAULT NULL, `enterdate` date DEFAULT NULL, `classname` varchar(10) DEFAULT NULL, `email` varchar(15) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci */
-
数据库表列类型
DML_添加数据
-
注意事项
-
int 宽度是显示宽度,如果超过,可以自动增大宽度 int 底层都是4个字节
-
时间的方式多样
'1256-12-23' "1256/12/23" "1256.12.23" -
字符串不区分单引号和双引号
-
如何写入当前的时间
now() , sysdate() , CURRENT_DATE() -
char varchar是字符的个数,不是字节的个数,可以使用binary,varbinary表示定长和不定长的字节个数 -
如果不是全字段插入数据的话,需要加入字段的名字
-- 查看表记录: select * from t_student; -- 在t_student数据库表中插入数据: insert into t_student values (1,'张三','男',18,'2022-5-8','软件1班','123@126.com'); insert into t_student values (10010010,'张三','男',18,'2022-5-8','软件1班','123@126.com'); insert into t_student values (2,'张三','男',18,'2022.5.8','软件1班','123@126.com'); insert into t_student values (2,"张三",'男',18,'2022.5.8','软件1班','123@126.com'); insert into t_student values (7,"张三",'男',18,now(),'软件1班','123@126.com'); insert into t_student values (9,"易烊千玺",'男',18,now(),'软件1班','123@126.com'); insert into t_student (sno,sname,enterdate) values (10,'李四','2023-7-5'); -
DML_修改,删除数据
-
注意事项
-- 修改表中数据 update t_student set sex = '女' ; update t_student set sex = '男' where sno = 10 ; UPDATE T_STUDENT SET AGE = 21 WHERE SNO = 10; update t_student set CLASSNAME = 'java01' where sno = 10 ; update t_student set CLASSNAME = 'JAVA01' where sno = 9 ; update t_student set age = 29 where classname = 'java01'; -- 删除操作: delete from t_student where sno = 2;
DDL_修改,删除数据库表
-
sql语言
-- 查看数据: select * from t_student; -- 修改表的结构: -- 增加一列: alter table t_student add score double(5,2) ; -- 5:总位数 2:小数位数 update t_student set score = 123.5678 where sno = 1 ; -- 增加一列(放在最前面) alter table t_student add score double(5,2) first; -- 增加一列(放在sex列的后面) alter table t_student add score double(5,2) after sex; -- 删除一列: alter table t_student drop score; -- 修改一列: alter table t_student modify score float(4,1); -- modify修改是列的类型的定义,但是不会改变列的名字 alter table t_student change score score1 double(5,1); -- change修改列名和列的类型的定义 -- 删除表: drop table t_student;
表的完整性约束
-
概述
-
MySQL中主要支持以下几种种完整性约束,如表所示。 其中Check约束是MySQL8中提供的支持

-
非外键约束
-
【1】代码演示非外键约束:
/* 建立一张用来存储学生信息的表 字段包含学号、姓名、性别,年龄、入学日期、班级,email等信息 约束: 建立一张用来存储学生信息的表 字段包含学号、姓名、性别,年龄、入学日期、班级,email等信息 【1】学号是主键 = 不能为空 + 唯一 ,主键的作用:可以通过主键查到唯一的一条记录 【2】如果主键是整数类型,那么需要自增 【3】姓名不能为空 【4】Email唯一 【5】性别默认值是男 【6】性别只能是男女 【7】年龄只能在18-50之间 */ -- 创建数据库表: create table t_student( sno int(6) primary key auto_increment, sname varchar(5) not null, sex char(1) default '男' check(sex='男' || sex='女'), age int(3) check(age>=18 and age<=50), enterdate date, classname varchar(10), email varchar(15) unique ); -- 添加数据: -- 1048 - Column 'sname' cannot be null 不能为null -- 3819 - Check constraint 't_student_chk_1' is violated. 违反检查约束 insert into t_student values (1,'张三','男',21,'2023-9-1','java01班','zs@126.com'); -- 1062 - Duplicate entry '1' for key 't_student.PRIMARY' 主键重复 -- > 1062 - Duplicate entry 'ls@126.com' for key 't_student.email' 违反唯一约束 insert into t_student values (2,'李四','男',21,'2023-9-1','java01班','ls@126.com'); insert into t_student values (3,'露露','男',21,'2023-9-1','java01班','ls@126.com'); -- 如果主键没有设定值,或者用null.default都可以完成主键自增的效果 insert into t_student (sname,enterdate) values ('菲菲','2029-4-5'); insert into t_student values (null,'小明','男',21,'2023-9-1','java01班','xm@126.com'); insert into t_student values (default,'小刚','男',21,'2023-9-1','java01班','xg@126.com'); -- 如果sql报错,可能主键就浪费了,后续插入的主键是不连号的,我们主键也不要求连号的 insert into t_student values (null,'小明','男',21,'2023-9-1','java01班','oo@126.com'); -- 查看数据: select * from t_student; -
【2】约束从作用上可以分为两类:
-
表级约束:可以约束表中任意一个或多个字段。与列定义相互独立,不包含在列定义中;与定义用‘,’分隔;必须指出要约束的列的名称
-
列级约束:包含在列定义中,直接跟在该列的其它定义之后 ,用空格分隔;不必指定列名
-- 删除表: drop table t_student; -- 创建数据库表: create table t_student( sno int(6) auto_increment, sname varchar(5) not null, sex char(1) default '男', age int(3), enterdate date, classname varchar(10), email varchar(15), constraint pk_stu primary key (sno), -- pk_stu 主键约束的名字 constraint ck_stu_sex check (sex = '男' || sex = '女'), constraint ck_stu_age check (age >= 18 and age <= 50), constraint uq_stu_email unique (email) ); -- 添加数据: insert into t_student values (1,'张三','男',21,'2023-9-1','java01班','zs@126.com'); -- > 3819 - Check constraint 'ck_stu_sex' is violated. -- > 3819 - Check constraint 'ck_stu_age' is violated. -- > 1062 - Duplicate entry 'zs@126.com' for key 't_student.uq_stu_email' insert into t_student values (3,'李四','男',21,'2023-9-1','java01班','zs@126.com'); -- 查看数据: select * from t_student; -
-
【3】在创建表以后添加约束:
-- 删除表: drop table t_student; -- 创建数据库表: create table t_student( sno int(6), sname varchar(5) not null, sex char(1) default '男', age int(3), enterdate date, classname varchar(10), email varchar(15) ); --> 1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key --> 错误的解决办法:就是auto_increment去掉 -- 在创建表以后添加约束: alter table t_student add constraint pk_stu primary key (sno) ; -- 主键约束 alter table t_student modify sno int(6) auto_increment; -- 修改自增条件 alter table t_student add constraint ck_stu_sex check (sex = '男' || sex = '女'); alter table t_student add constraint ck_stu_age check (age >= 18 and age <= 50); alter table t_student add constraint uq_stu_email unique (email); -- 查看表结构: desc t_student; -
【4】总结:
-
主键约束
-
非空约束
-
唯一约束
-
检查约束
-
默认值约束
-
字段值自动增加约束
-
自增约束(AUTO_INCREMENT)可以使表中某个字段的值自动增加
-
一张表中只能有一个自增长字段,并且该字段必须定义了约束(该约束可以是主键约束、唯一约束以及外键约束),如果自增字段没有定义约束,数据库则会提示
“Incorrect table definition; there can be only one auto column and it must be defined as a key”错误 -
由于自增约束会自动生成唯一的ID,所以自增约束通常会配合主键使用,并且只适用于整数类型。一般情况下,设置为自增约束字段的值会从1开始,每增加一条记录,该字段的值加1
-
为已存在表中的字段添加自增约束
/*创建表student11*/ create table student11 ( stu_id int(10) primary key, stu_name varchar(3), stu_sex varchar(1) ); /*为student11表中的主键字段添加自增约束*/ alter table student11 modify stu_id int(10) auto_increment; -
使用ALTER TABLE语句删除自增约束
alter table student11 modify stu_id int(10);
-
-
-
-
外键约束
-
【1】什么是外键约束?
-
【2】sql展示:
-- 先创建父表:班级表: create table t_class( cno int(4) primary key auto_increment, cname varchar(10) not null, room char(4) ) -- 添加班级数据: insert into t_class values (null,'java001','r803'); insert into t_class values (null,'java002','r416'); insert into t_class values (null,'大数据001','r103'); -- 可以一次性添加多条记录: insert into t_class values (null,'java001','r803'),(null,'java002','r416'),(null,'大数据001','r103'); -- 查询班级表: select * from t_class; -- 学生表删除: drop table t_student; -- 创建子表, 学生表: create table t_student( sno int(6) primary key auto_increment, sname varchar(5) not null, classno int(4) -- 取值参考t_class表中的cno字段,不要求字段名字完全重复,但是类型长度定义 尽量要求相同 ); -- 添加学生信息: insert into t_student values (null,'张三',1),(null,'李四',1),(null,'王五',2); -- 查看学生表: select * from t_student; -- 出现问题: -- 1.添加一个学生对应的班级编码为4: insert into t_student values (null,'丽丽',4); -- 2.删除班级2: delete from t_class where cno = 2; -- 出现问题的原因: -- 因为你现在的外键约束,没用语法添加进去,现在只是逻辑上认为班级编号是外键,没有从语法上定义 -- 解决办法,添加外键约束: -- 注意:外键约束只有表级约束,没有列级约束: create table t_student( sno int(6) primary key auto_increment, sname varchar(5) not null, classno int(4), -- 取值参考t_class表中的cno字段,不要求字段名字完全重复,但是类型长度定义 尽量要求相同 ); create table t_student( sno int(6) primary key auto_increment, sname varchar(5) not null, classno int(4) ); -- 在创建表以后添加外键约束: alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) -- 上面的两个问题都解决了: -- 添加学生信息: -- > 1452 - Cannot add or update a child row: a foreign key constraint fails (`mytestdb`.`t_student`, CONSTRAINT `fk_stu_classno` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`)) insert into t_student values (null,'张三',1),(null,'李四',1),(null,'王五',2); -- 删除班级1: -- 2.删除班级2: insert into t_student values (null,'张三',3),(null,'李四',3),(null,'王五',3); -- > 1451 - Cannot delete or update a parent row: a foreign key constraint fails (`mytestdb`.`t_student`, CONSTRAINT `fk_stu_classno` FOREIGN KEY (`classno`) REFERENCES `t_class` (`cno`)) delete from t_class where cno = 3;
-
-
外键策略
-- 学生表删除: drop table t_student; -- 班级表删除: drop table t_class; -- 注意:先删除从表,再删除主表 -- 先创建父表:班级表: create table t_class( cno int(4) primary key auto_increment, cname varchar(10) not null, room char(4) ) -- 可以一次性添加多条记录: insert into t_class values (null,'java001','r803'),(null,'java002','r416'),(null,'大数据001','r103'); -- 添加学生表,添加外键约束: create table t_student( sno int(6) primary key auto_increment, sname varchar(5) not null, classno int(4), -- 取值参考t_class表中的cno字段,不要求字段名字完全重复,但是类型长度定义 尽量要求相同 ); -- 可以一次性添加多条记录: insert into t_student values (null,'张三',1),(null,'李四',1),(null,'王五',2),(null,'朱六',3); -- 查看班级表和学生表: select * from t_class; select * from t_student; -- 删除班级2:如果直接删除的话肯定不行因为有外键约束: -- 加入外键策略: -- 策略1:no action 不允许操作 -- 通过操作sql来完成: -- 先把班级2的学生对应的班级 改为null update t_student set classno = null where classno = 2; -- 然后再删除班级2: delete from t_class where cno = 2; -- 策略2:cascade 级联操作:操作主表的时候影响从表的外键信息: -- 先删除之前的外键约束: alter table t_student drop foreign key fk_stu_classno; -- 重新添加外键约束: alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update cascade on delete cascade; -- 试试更新: update t_class set cno = 5 where cno = 3; -- 试试删除: delete from t_class where cno = 5; -- 策略3:set null 置空操作: -- 先删除之前的外键约束: alter table t_student drop foreign key fk_stu_classno; -- 重新添加外键约束: alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update set null on delete set null; -- 试试更新: update t_class set cno = 8 where cno = 1; -- 注意: -- 1. 策略2 级联操作 和 策略2 的 删除操作 可以混着使用: alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update cascade on delete set null ; -- 2.应用场合: -- (1)朋友圈删除,点赞。留言都删除 -- 级联操作 -- (2)解散班级,对应的学生 置为班级为null就可以了,-- set null
-
DDL和DML的补充
-
【1】sql展示:
-- 创建表: create table t_student( sno int(6) primary key auto_increment, sname varchar(5) not null, sex char(1) default '男' check(sex='男' || sex='女'), age int(3) check(age>=18 and age<=50), enterdate date, classname varchar(10), email varchar(15) unique ); -- 添加数据: insert into t_student values (null,'张三','男',21,'2023-9-1','java01班','zs@126.com'); insert into t_student values (null,'李四','男',21,'2023-9-1','java01班','ls@126.com'); insert into t_student values (null,'露露','男',21,'2023-9-1','java01班','ll@126.com'); -- 查看学生表: select * from t_student; -- 添加一张表:快速添加:结构和数据跟 t_student 都是一致的 create table t_student2 as select * from t_student; select * from t_student2; -- 快速添加,结构跟t_student一致,数据没有: create table t_student3 as select * from t_student where 1=2; select * from t_student3; -- 快速添加:只要部分列,部分数据: create table t_student4 as select sno, sname, age from t_student where sno = 2; select * from t_student4; -- 删除数据操作 :清空数据 delete from t_student; truncate table t_student; -
【2】
delete和truncate的区别:-
(1)
DELETE为数据操作语言DML;TRUNCATE为数据定义语言DDL -
(2)
DELETE操作是将表中所有记录一条一条删除直到删除完,TRUNCATE操作则是保留了表的结构,重新创建了这个表,所有的状态都相当于新表, 因此,TRUNCATE操作的效率更高 -
(3)
DELETE操作可以回滚;TRUNCATE操作会导致隐式提交,因此不能回滚 -
(4)
DELETE操作执行成功后会返回已删除的行数(如删除4行记录,则会显示“Affected rows:4”);截断操作不会返回已删除的行量,结果通常是“Affected rows:0”。DELETE操作删除表中记录后,再次向表中添加新记录时,对于设置有自增约束字段的值会从删除前表中该字段的最大值加1开始自增;TRUNCATE操作则会重新从1开始自增
-
DQL-查询操作
-
表的准备
-
准备四张表:dept(部门表), emp(员工表), salgrade(薪资等级表), bonus(奖金表)
create table DEPT( DEPTNO int(2) not null, DNAME VARCHAR(14), LOC VARCHAR(13) alter table DEPT add constraint PK_DEPT primary key (DEPTNO); create table EMP ( EMPNO int(4) primary key, ENAME VARCHAR(10), JOB VARCHAR(9), MGR int(4), HIREDATE DATE, SAL double(7,2), COMM double(7,2), DEPTNO int(2) ); alter table EMP add constraint FK_DEPTNO foreign key (DEPTNO) references DEPT (DEPTNO); create table SALGRADE ( GRADE int primary key, LOSAL double(7,2), HISAL double(7,2) ); create table BONUS ( ENAME VARCHAR(10), JOB VARCHAR(9), SAL double(7,2), COMM double(7,2) ); insert into DEPT (DEPTNO, DNAME, LOC) values (10, 'ACCOUNTING', 'NEW YORK'); insert into DEPT (DEPTNO, DNAME, LOC) values (20, 'RESEARCH', 'DALLAS'); insert into DEPT (DEPTNO, DNAME, LOC) values (30, 'SALES', 'CHICAGO'); insert into DEPT (DEPTNO, DNAME, LOC) values (40, 'OPERATIONS', 'BOSTON'); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, null, 20); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, null, 20); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20); insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10); insert into SALGRADE (GRADE, LOSAL, HISAL) values (1, 700, 1200); insert into SALGRADE (GRADE, LOSAL, HISAL) values (2, 1201, 1400); insert into SALGRADE (GRADE, LOSAL, HISAL) values (3, 1401, 2000); insert into SALGRADE (GRADE, LOSAL, HISAL) values (4, 2001, 3000); insert into SALGRADE (GRADE, LOSAL, HISAL) values (5, 3001, 9999); -- 查看表: select * from dept; -- 部门表:dept:department 部分 ,loc - location 位置 select * from emp; -- 员工表:emp:employee 员工, mgr: manager上级领导编号,hiredate 入职日期 firedate 解雇日期 ,common:补助 -- deptno 外键 参考 dept - deptno字段 -- mgr 外键 参考 自身表emp - empno 产生了自关联 select * from salgrade; -- losal - lowsal -- hisal - highsal select * from bonus;
-
-
单表查询
-
最简单的SQL查询
-- 对emp表查询: select * from emp; -- *代表所有数据 -- 显示部分列: select empno, ename, sal from emp; -- 显示部分行:where子句 select * from emp where sal > 2000; -- 显示部分列,部分行: select empno, ename, job, mgr from emp where sal > 2000; -- 起别名: select empno 员工编号, ename 姓名, sal 工资 from emp; -- as 省略,''或者""省略了 -- as alias 别名 select empno as 员工编号, ename as 姓名, sal as 工资 from emp; select empno as '员工编号', ename as "姓名", sal as 工资 from emp; -- > 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '编号,ename as "姓 名",sal as 工资 from emp' at line 1 -- 错误原因:在别名中有特殊符号的时候,''或者""不可以省略不写 select empno as 员工 编号,ename as "姓名", sal as 工资 from emp; -- 算术运算符: select empno, ename, sal, sal + 1000 as '涨薪后', deptno from emp where sal < 2500; select empno, ename, sal, comm, sal + comm from emp; -- ???后面再说 -- 去重操作: select job from emp; select distinct job from emp; select job,deptno from emp; select distinct job,deptno from emp; -- 对后面的所有列组合 去重 ,而不是单独的某一列去重 -- 排序: select * from emp order by sal; -- 默认情况下是按照升序排列的 select * from emp order by sal asc; -- asc 升序,可以默认不写 select * from emp order by sal desc; -- desc 降序 select * from emp order by sal asc, deptno desc; -- 在工资升序的情况下,deptno 按照降序排列 -
where子句
-- 查看emp表: select * from emp; -- where子句:将过滤条件放在where子句的后面,可以筛选/过滤出我们想要的符合条件的数据: -- where 子句 + 关系运算符 select * from emp where deptno = 10; select * from emp where deptno > 10; select * from emp where deptno >= 10; select * from emp where deptno < 10; select * from emp where deptno <= 10; select * from emp where deptno <> 10; select * from emp where deptno != 10; select * from emp where job = 'CLERK'; select * from emp where job = 'clerk'; -- 默认情况下不区分大小写 select * from emp where binary job = 'clerk'; -- binary区分大小写 select * from emp where hiredate < '1981-12-25'; -- where 子句 + 逻辑运算符:and select * from emp where sal > 1500 and sal < 3000; -- (1500,3000) select * from emp where sal > 1500 && sal < 3000; select * from emp where sal > 1500 and sal < 3000 order by sal; select * from emp where sal between 1500 and 3000; -- [1500,3000] -- where 子句 + 逻辑运算符:or select * from emp where deptno = 10 or deptno = 20; select * from emp where deptno = 10 || deptno = 20; select * from emp where deptno in (10,20); select * from emp where job in ('MANAGER','CLERK','ANALYST'); -- where子句 + 模糊查询: -- 查询名字中带A的员工 -- %代表任意多个字符 0,1,2,..... select * from emp where ename like '%A%' ; -- -任意一个字符 select * from emp where ename like '__A%' ; -- 关于null的判断: select * from emp where comm is null; select * from emp where comm is not null; -- 小括号的使用 :因为不同的运算符的优先级别不同,加括号为了可读性 select * from emp where job = 'SALESMAN' or job = 'CLERK' and sal >= 1500; -- 先and再or and > or select * from emp where job = 'SALESMAN' or (job = 'CLERK' and sal >= 1500); select * from emp where (job = 'SALESMAN' or job = 'CLERK') and sal >= 1500; -
使用函数
-
概述
-
单行函数是指对每一条记录输入值进行计算,并得到相应的计算结果,然后返回给用户,也就是说,每条记录作为一个输入参数,经过函数计算得到每条记录的计算结果
-
常用的单行函数主要包括字符串函数、数值函数、日期与时间函数、流程函数以及其他函数
-
多行函数是指对一组数据进行运算,针对这一组数据(多行记录)只返回一个结果,也称为分组函数
-- 函数举例: select empno, ename, lower(ename), upper(ename), sal from emp; -- 函数的功能:封装了特定的一些功能,我们直接拿过来使用,可以实现对应的功能 -- 函数作用:为了提高select的能力 -- 注意:函数没有改变数据自身的值,而是在真实数据的上面进行加工处理,展示新的结果而已 select max(sal), min(sal), count(sal), sum(sal), avg(sal) from emp; -- 函数的分类: -- lower(ename), upper(ename): 改变每一条结果,每一条数据对应一条结果 -- 单行函数 -- max(sal), min(sal), count(sal), sum(sal), avg(sal): 多条数据,最终展示一个结果 -- 多行函数 -
-
单行函数
函数 描述 CONCAT(str1, str2, … strn) 将str1、str2…strn拼接成一个新的字符串 INSERT(str, index, n, newstr) 将字符串str从第index位置开始的n个字符替换成字符串newstr LENGTH(str) 获取字符串str的长度 LOWER(str) 将字符串str中的每个字符转换为小写 UPPER(str) 将字符串str中的每个字符转换为大写 LEFT(str, n) 获取字符串str最左边的n个字符 RIGHT(str, n) 获取字符串str最右边的n个字符 LPAD(str, n, pad) 使用字符串pad在str的最左边进行填充,直到长度为n个字符为止 RPAD(str, n, pad) 使用字符串pad在str的最右边进行填充,直到长度为n个字符为止 LTRIM(str) 去除字符串str左侧的空格 RTRIM(str) 去除字符串str右侧的空格 TRIM(str) 去除字符串str左右两侧的空格 REPLACE(str, oldstr, newstr) 用字符串newstr替换字符串str中所有的子字符串oldstr REVERSE(str) 将字符串str中的字符逆序 STRCMP(str1, str2) 比较字符串str1和str2的大小 SUBSTRING(str, index, n) 获取从字符串str的index位置开始的n个字符 函数 描述 ABS(num) 返回num的绝对值 CEIL(num) 返回大于num的最小整数(向上取整) FLOOR(num) 返回小于num的最大整数(向下取整) MOD(num1, num2) 返回num1/num2的余数(取模) PI() 返回圆周率的值 POW(num,n)/POWER(num, n) 返回num的n次方 RAND(num) 返回0~1之间的随机数 ROUND(num, n) 返回四舍五入后的值,该值保留到小数点后n位 TRUNCATE(num, n) 返回num被舍去至小数点后n位的值 函数 描述 CURDATE() 返回当前日期 CURTIME() 返回当前时间 NOW() 返回当前日期和时间 SYSDATE() 返回该函数执行时的日期和时间 DAYOFYEAR(date) 返回日期date为一年中的第几天 WEEK(date)/WEEKOFYEAR(date) 返回日期date为一年中的第几周 DATE_FORMAT(date, format) 返回按字符串format格式化后的日期date DATE_ADD(date, INTERVAL expr unit) 返回date加上一个时间间隔后的新时间值 /ADDDATE(date, INTERVAL expr unit) 返回date减去一个时间间隔后的新时间值 DATE_SUB(date, INTERVAL expr unit) 返回date减去一个时间间隔后的新时间值 /SUBDATE(date, INTERVAL expr unit) 返回date减去一个时间间隔后的新时间值 DATEDIFF(date1, date2) 返回起始日期date1与结束日期date2之间的间隔天数 -- 单行函数包含: -- 1.字符串函数 select ename, length(ename), substring(ename, 2, 3) from emp; -- substring字符串截取,2: 从字符下标为2开始,3: 截取长度3 (下标从1开始) -- 2.数值函数 select abs(-5), ceil(5.3), floor(5.9), round(3.14) from dual; -- dual实际就是一个伪表 select abs(-5) 绝对值, ceil(5.3) 向上取整, floor(5.9) 向下取整, round(3.14) 四舍五入; -- 如果没有where条件的话,from dual可以省略不写 select ceil(sal) from emp; select 10/3, 10%3, mod(10,3) ; -- 3.日期与时间函数 select * from emp; select curdate(), curtime() ; -- curdate()年月日 curtime()时分秒 select now(), sysdate(), sleep(3), now(), sysdate() from dual; -- now(), sysdate() 年月日时分秒 -- NOW() 在同一语句中值是固定的 SELECT NOW(), SLEEP(3), NOW(); -- 结果:两个时间一样,都是语句开始时的时间 -- SYSDATE() 会随着执行时刻变化 SELECT SYSDATE(), SLEEP(3), SYSDATE(); -- 结果:第二个时间比第一个晚了3秒 insert into emp values (9999,'lili','SALASMAN',7698,now(),1000,null,30); -- now()可以表示年月日时分秒,但是插入数据的时候还是要参照表的结构的 desc emp;函数 描述 IF(condition, t, f) 如果条件condition为真,则返回t,否则返回f IFNULL(value1, value2) 如果value1不为null,则返回value1,否则返回value2 NULLIF(value1, value2) 如果value1等于value2,则返回null,否则返回value1 CASE value WHEN [value1] THEN result1 [WHEN [value2] THEN result2 …] [ELSE result] END 如果value等于value1,则返回result1,否则返回result CASE WHEN [condition1] THEN result1 [WHEN [condition2] THEN result2 …] [ELSE result] END 如果条件condition1为真,则返回result1,否则返回 result 函数 描述 JSON_APPEND() 在JSON文档中追加数据 JSON_INSERT() 在JSON文档中插入数据 JSON_REPLACE() 替换JSON文档中的数据 JSON_REMOVE() 从JSON文档的指定位置移除数据 JSON_CONTAINS() 判断JSON文档中是否包含某个数据 JSON_SEARCH() 查找JSON文档中给定字符串的路径 函数 描述 DATABASE() 返回当前数据库名 VERSION() 返回当前MySQL的版本号 USER() 返回当前登录的用户名 INET_ATON(IP) 返回IP地址的数字表示 INET_NTOA() 返回数字代表的IP地址 PASSWORD(str) 实现对字符串str的加密操作 FORMAT(num, n) 实现对数字num的格式化操作,保留n位小数 CONVERT(data, type) 实现将数据data转换成type类型的操作 -- 4.流程函数 -- if相关 select empno, ename, sal, if(sal >= 2500, '高薪', '底薪') as '薪资等级' from emp; -- if-else 双分支结构 select empno, ename, sal, comm, sal + ifnull (comm, 0) from emp; -- 如果comm是null,那么取值为0 -- 单分支 select nullif(1, 1), nullif(1, 2) from dual; -- 如果value1等于value2,则返回null,否则返回value1 -- case相关: -- case等值判断 select empno, ename, job, case job when 'CLERK' then '店员' when 'SALESMAN' then '销售' when 'MANAGER' then '经理' else '其他' end '岗位', sal from emp; -- case区间判断: select empno, ename, sal, case when sal <= 1000 then 'A' when sal <= 2000 then 'B' when sal <= 3000 then 'C' else 'D' end '工资等级', deptno from emp; from emp; -- 5.JSON函数 -- 6.其他函数 select database(), user(), version() from dual; -
多行函数
-
对一组数据进行运算,针对一组数据(多行记录)只返回一个结果,也称分组函数

-
多行函数包含:
函数 描述 COUNT()统计表中记录的数目 SUM()计算指定字段值的总和 AVG()计算指定字段值的平均值 MAX()统计指定字段值的最大值 MIN()统计指定字段值的极小值 -- 多行函数: select max(sal), min(sal), count(sal), sum(sal), sum(sal) / count(sal), avg(sal) from emp; select * from emp; -- 多行函数自动忽略null值 select max(comm), min(comm), count(comm), sum(comm), sum(comm) / count(comm), avg(comm) from emp; -- max(),min(),count()针对所有类型 sum(),avg() 只针对数值型类型有效 select max(ename), min(ename), count(ename), sum(ename), avg(ename) from emp; -- count --计数 -- 统计表的记录数:方式1: select * from emp; select count(ename) from emp; select count(*) from emp; -- 统计表的记录数:方式2 select 1 from dual; select 1 from emp; select count(1) from emp;
-
-
-
group_by分组
-
用来进行分组
-
sql展示:
select * from emp; -- 统计各个部门的平均工资 select deptno, avg(sal) from emp; -- 字段和多行函数不可以同时使用 select deptno, avg(sal) from emp group by deptno; -- 字段和多行函数不可以同时使用,除非这个字段属于分组 select deptno, avg(sal) from emp group by deptno order by deptno desc; -- 统计各个岗位的平均工资 select job, avg(sal) from emp group by job; select job, lower(job), avg(sal) from emp group by job;
-
-
having分组后筛选
-
sql代码
-- 统计各个部门的平均工资 ,只显示平均工资2000以上的 - 分组以后进行二次筛选 having select deptno, avg(sal) from emp group by deptno having avg(sal) > 2000; select deptno, avg(sal) 平均工资 from emp group by deptno having 平均工资 > 2000; select deptno, avg(sal) 平均工资 from emp group by deptno having 平均工资 > 2000 order by deptno desc; -- 统计各个岗位的平均工资,除了MANAGER -- 方法1: select job, avg(sal) from emp where job != 'MANAGER' group by job; -- 方法2: select job, avg(sal) from emp group by job having job != 'MANAGER'; -- where在分组前进行过滤的,having在分组后进行后滤
-
-
单表查询总结
-
【1】select语句总结
select column, group_function(column) from table [where condition] [group by group_by_expression] [having group_condition] [order by column] -- 注意:顺序固定,不可以改变顺序 -
【2】select语句的执行顺序
-
【3】单表查询练习:
-- 单表查询练习: -- 列出工资最小值小于2000的职位 select job, min(sal) from emp group by job having min(sal) < 2000; -- 列出平均工资大于1200元的部门和工作搭配组合 select deptno, job, avg(sal) from emp group by deptno, job having avg(sal) > 1200 order by deptno; -- 统计[人数小于4的]部门的平均工资 select deptno, count(1), avg(sal) from emp group by deptno having count(1) < 4 -- 统计各部门的最高工资,排除最高工资小于3000的部门 select deptno, max(sal) from emp group by deptno having max(sal) < 3000;
-
-
-
多表查询
-
99语法:交叉连接,自然连接,内连接查询
-
【1】多表查询引入:
-
实际开发中往往需要针对两张甚至更多张数据表进行操作,而这多张表之间需要使用主键和外键关联在一起,然后使用连接查询来查询多张表中满足要求的数据记录
-
一条SQL语句查询多个表,得到一个结果,包含多个表的数据。效率高。在SQL99中,连接查询需要使用join关键字实现
-
提供了多种连接查询的类型:
cross natural using on -
交叉连接(CROSS JOIN)是对两个或者多个表进行笛卡儿积操作,所谓笛卡儿积就是关系代数里的一个概念,表示两个表中的每一行数据任意组合的结果
-
比如:有两个表,左表有m条数据记录,x个字段,右表有n条数据记录,y个字段,则执行交叉连接后将返回m*n条数据记录,x+y个字段。笛卡儿积示意图如图所示

-
-
【2】sql展示:
-- 查询员工的编号,姓名,部门编号: select * from emp; select empno, ename, deptno from emp; -- 查询员工的编号,姓名,部门编号,部门名称: select * from emp; -- 14条记录 select * from dept; -- 4条记录 -- 多表查询 : -- 交叉连接:cross join select * from emp cross join dept; -- 14*4 = 56条 笛卡尔乘积 : 没有实际意义,有理论意义 select * from emp join dept; -- cross可以省略不写,mysql中可以,oracle中不可以 -- 自然连接:natural join -- 优点:自动匹配所有的同名列, 同名列只展示一次 ,简单 select * from emp natural join dept; select empno, ename, sal, dname, loc from emp natural join dept; -- 缺点:查询字段的时候,没有指定字段所属的数据库表,效率低 -- 解决:指定表名: select emp.empno, emp.ename, emp.sal, dept.dname, dept.loc, dept.deptno from emp natural join dept; -- 缺点:表名太长 -- 解决:表起别名 select e.empno, e.ename, e.sal, d.dname, d.loc, d.deptno from emp e natural join dept d; -- 自然连接 natural join -- 缺点:自动匹配表中所有的同名列,但是有时候我们希望只匹配部分同名列: -- 解决:内连接 - using子句 select * from emp e inner join dept d --inner可以不写 using(deptno) -- 这里不能写natural join了, 这里是内连接 -- using缺点:关联的字段,必须是同名的 -- 解决: 内连接 - on子句: select * from emp e inner join dept d on (e.deptno = d.deptno); -- 多表连接查询的类型: 1.交叉连接 cross join 2. 自然连接 natural join -- 3. 内连接 - using子句 4.内连接 - on子句 -- 综合看:内连接 - on子句 select * from emp e inner join dept d on (e.deptno = d.deptno) where sal > 3500; -- 条件: -- 1.筛选条件 where having -- 2.连接条件 on,using,natural -- SQL99语法:筛选条件和连接条件是分开的
-
-
99语法:外连接查询
-- inner join - on子句: 显示的是所有匹配的信息 select * from emp e inner join dept d on e.deptno = d.deptno; select * from emp; select * from dept; -- 问题: -- 1.40号部分没有员工,没有显示在查询结果中 -- 2.员工scott没有部门,没有显示在查询结果中 -- 外连接:除了显示匹配的数据之外,还可以显示不匹配的数据 -- 左外连接: left outer join -- 左面的那个表的信息,即使不匹配也可以查看出效果 select * from emp e left outer join dept d on e.deptno = d.deptno; -- 右外连接: right outer join -- 右面的那个表的信息,即使不匹配也可以查看出效果 select * from emp e right outer join dept d on e.deptno = d.deptno; -- 全外连接 full outer join -- 这个语法在mysql中不支持,在oracle中支持 -- 展示左,右表全部不匹配的数据 -- scott, 40号部门都可以看到 select * from emp e full outer join dept d on e.deptno = d.deptno; -- 解决mysql中不支持全外连接的问题: select * from emp e left outer join dept d on e.deptno = d.deptno union -- 并集 去重 效率低 select * from emp e right outer join dept d on e.deptno = d.deptno; select * from emp e left outer join dept d on e.deptno = d.deptno union all -- 并集 不去重 效率高 select * from emp e right outer join dept d on e.deptno = d.deptno; -- mysql 中对集合操作支持比较弱,只支持并集操作,交集,差集不支持(oracle中支持) -- outer 可以省略不写 -
99语法:三表连接查询
-- 查询员工的编号、姓名、薪水、部门编号、部门名称、薪水等级 select * from emp; select * from dept; select * from salgrade; select e.ename, e.sal, e.empno, e.deptno, d.dname, s.* from emp e right outer join dept d on e.deptno = d.deptno inner join salgrade s on e.sal between s.losal and s.hisal -
99语法:自连接查询

-- 查询员工的编号、姓名、上级编号,上级的姓名 select * from emp; select e1.empno 员工编号, e1.ename 员工姓名, e1.mgr 领导编号, e2.ename 员工领导姓名 from emp e1 inner join emp e2 on e1.mgr = e2.empno; -- 左外连接: select e1.empno 员工编号, e1.ename 员工姓名, e1.mgr 领导编号, e2.ename 员工领导姓名 from emp e1 left outer join emp e2 on e1.mgr = e2.empno; -
92语法:多表查询
-- 查询员工的编号,员工姓名,薪水,员工部门编号,部门名称: select e.empno, e.ename, e.sal, e.deptno, d.dname from emp e, dept d -- 相当于99语法中的 cross join, 出现笛卡尔积,没有意义 select e.empno, e.ename, e.sal, e.deptno, d.dname from emp e, dept d where e.deptno = d.deptno; -- 相当于99语法中的 natural join -- 查询员工的编号,员工姓名,薪水,员工部门编号,部门名称,查询出工资大于2000的员工 select e.empno, e.ename, e.sal, e.deptno, d.dname from emp e, dept d where e.deptno = d.deptno and e.sal > 2000; -- 查询员工的名字,岗位,上级编号,上级名称(自连接): select e1.ename, e1.job, e1.mgr, e2.ename from emp e1, emp e2 where e1.mgr = e2.empno; -- 查询员工的编号、姓名、薪水、部门编号、部门名称、薪水等级 select e.empno, e.ename, e.sal, e.deptno, d.dname,s.grade from emp e, dept d, salgrade s where e.deptno = d.deptno and e.sal >= s.losal and e.sal <= s.hisal; -- 总结: -- 1.92语法麻烦 -- 2.92语法中 表的连接条件 和 筛选条件 是放在一起的没有分开 -- 3.99语法中提供了更多的查询连接类型:cross, natural, inner, outer
-
-
子查询
-
不相关子查询
-
概述
-
【1】什么是子查询?
-
一条SQL语句含有多个select
-- 引入子查询: -- 查询所有比“CLARK”工资高的员工的信息 -- 步骤1:“CLARK”工资 select sal from emp where ename = 'CLARK' -- 2450 -- 步骤2:查询所有工资比2450高的员工的信息 select * from emp where sal > 2450; -- 两次命令解决问题 --> 效率低,第二个命令依托于第一个命令,第一个命令的结果给第二个命令使用 -- 但是因为第一个命令的结果可能不确定要改,所以第二个命令也会导致修改 -- 将步骤1和步骤2合并 --> 子查询: select * from emp where sal > (select sal from emp where ename = 'CLARK'); -- 一个命令解决问题 --> 效率高
-
-
【2】执行顺序:
-
【3】不相关子查询:
-
【4】不相关子查询分类:
-
-
-
相关子查询
-
【1】不相关的子查询引入:
-
【2】不相关的子查询优缺点:
-
【3】sql展示:
-- 【1】查询最高工资的员工 (不相关子查询) select * from emp where sal = (select max(sal) from emp) -- 【2】查询本部门最高工资的员工 (相关子查询) -- 方法1:通过不相关子查询实现: select * from emp where deptno = 10 and sal = (select max(sal) from emp where deptno = 10) union select * from emp where deptno = 20 and sal = (select max(sal) from emp where deptno = 20) union select * from emp where deptno = 30 and sal = (select max(sal) from emp where deptno = 30) -- 缺点:语句比较多,具体到底有多少个部分未知 -- 方法2: 相关子查询 select * from emp e where sal = (select max(sal) from emp where deptno = e.deptno) order by deptno -- 【3】查询工资高于其所在岗位的平均工资的那些员工 (相关子查询) -- 不相关子查询: select * from emp where job = 'CLERK' and sal >= (select avg(sal) from emp where job = 'CLERK') union ...... -- 相关子查询: select * from emp e where sal >= (select avg(sal) from emp e2 where e2.job = e.job)
-
-
数据库对象
-
事务
-
事务及其特征
-
引入
-
【1】事务的概念
-
【2】事务的特性
-
【3】sql展示:使用事务保证转账安全
-- 创建账户表: create table account( id int primary key auto_increment, uname varchar(10) not null, balance double ); -- 查看账户表: select * from account; -- 在表中插入数据: insert into account values (null,'丽丽',2000), (null,'小刚',2000); -- 丽丽给小刚 转200元: update account set balance = balance - 200 where id = 1; update account set balance = balance + 200 where id = 2; -- 默认一个DML语句是一个事务,所以上面的操作执行了2个事务 update account set balance = balance - 200 where id = 1; update account set balance = balance2 + 200 where id = 2; -- 必须让上面的两个操作控制在一个事务中: -- 手动开启事务: start transaction; update account set balance = balance - 200 where id = 1; update account set balance = balance + 200 where id = 2; -- 手动回滚:刚才执行的操作全部取消: rollback; -- 手动提交: commit; -- 在回滚和提交之前,数据库中的数据都是操作的缓存中的数据,而不是数据库的真实数据
-
-
事务并发问题
-
事务隔离级别
-
事务的隔离级别用于决定如何控制并发用户读写数据的操作
-
数据库是允许多用户并发访问的,如果多个用户同时开启事务并对同一数据进行读写操作的话,有可能会出现脏读、不可重复读和幻读问题,所以MySQL中提供了四种隔离级别来解决上述问题
-
事务的隔离级别从低到高依次为
READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ以及SERIALIZABLE, 隔离级别越低,越能支持高并发的数据库操作隔离级别 脏读 不可重复读 幻读 READ UNCOMMITTED √ √ √ READ COMMITTED × √ √ REPEATABLE READ × × √ SERIALIZABLE × × × -- 查看默认的事务隔离级别 MySQL默认的是repeatable read select @@transaction_isolation; -- 设置事务的隔离级别 (设置当前会话的隔离级别) set session transaction isolation level read uncommitted; set session transaction isolation level read committed; set session transaction isolation level repeatable read; set session transaction isolation level serializable; start transaction; select * from account where id = 1;
-
-
-
视图
-
【1】视图的概念
-
【2】视图的好处
-
【3】SQL展示:
-- 创建/替换单表视图: create or replace view myview01 as select empno, ename, job, deptno from emp where deptno = 20 with check option; -- 查看视图: select * from myview01; -- 在视图中插入数据: insert into myview01 (empno,ename,job,deptno) values (9999,'lili','CLERK',20); insert into myview01 (empno,ename,job,deptno) values (8888,'nana','CLERK',30); insert into myview01 (empno,ename,job,deptno) values (7777,'feifei','CLERK',30); -- > 1369 - CHECK OPTION failed 'mytestdb.myview01' -- 创建/替换多表视图: create or replace view myview02 as select e.empno, e.ename, e.sal, d.deptno, d.dname from emp e join dept d on e.deptno = d.deptno where sal > 2000 ; select * from myview02; -- 创建统计视图: create or replace view myview03 as select e.deptno, d.dname, avg(sal), min(sal), count(1) from emp e join dept d using(deptno) group by e.deptno ; select * from myview03; -- 创建基于视图的视图: create or replace view myview04 as select * from myview03 where deptno = 20; select * from myview04;
-
-
存储过程
-
【1】什么是存储过程(Stored Procedure)
-
【2】存储过程的优点
-
【3】图解:

-
【4】展示存储过程:
-- 定义一个没有返回值 存储过程 -- 实现:模糊查询操作: select * from emp where ename like '%A%'; create procedure mypro01(name varchar(10)) begin if name is null or name = "" then select * from emp; else select * from emp where ename like concat('%', name, '%'); end if; end; -- 删除存储过程: drop procedure mypro01; -- 调用存储过程: call mypro01(null); call mypro01('R'); -- 定义一个 有返回值的存储过程: -- 实现:模糊查询操作: -- in 参数前面的in可以省略不写 -- found_rows()mysql 中定义的一个函数,作用返回查询结果的条数 create procedure mypro02(in name varchar(10),out num int(3)) begin if name is null or name = "" then select * from emp; else select * from emp where ename like concat('%',name,'%'); end if; select found_rows() into num; end; -- 调用存储过程: call mypro02(null, @num); select @num; call mypro02('R', @aaa); select @aaa;
-
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐









所有评论(0)