【Mysql 学习笔记】 DML 和 DDL语句(非常详细,结合多个案例快速入门)

DML 和 DDL



DML 数据操作语言

(1) 插入 (insert)

① 语法:

insert into 表名(字段名,...) values(,...);

② 特点:

特点:
1、要求值的类型和字段的类型要一致或兼容

2、字段的个数和顺序不一定与原始表中的字段个数和顺序一致
但必须保证值和字段一一对应

3、假如表中有可以为null的字段,注意可以通过以下两种方式插入null值
	字段和值都省略
	字段写上,值使用null

4、字段和值的个数必须一致

5、字段名可以省略,默认表中所有列

③ 使用 (不记录set方式):

练习一:
INSERT INTO admin(id,username,password)
VALUES(3,"admin","admin")

在这里插入图片描述


练习二 (支持插入多行):

插入多行,使用逗号隔开

INSERT INTO admin
VALUES(4,"admin1","admin1"),
	  (5,"admin2","admin2")

在这里插入图片描述


练习三 (支持子查询):

注意:values 没了,且特点依旧遵循上面

# 案例:把boys中id大于等于3的人插入到管理员
INSERT INTO admin
SELECT id,boyName,boyName
FROM boys
WHERE id>=3

在这里插入图片描述


(2) 修改 (update)

① 修改单表的记录:

语法:update 表名 set 字段=,字段=值 【where 筛选条件】;
练习一:
#案例1:修改admin表中名字以j开头的的管理员的密码为1111
UPDATE admin SET `password` = "1111"
WHERE username LIKE "j%"

在这里插入图片描述


练习二:
#案例1:修改admin表中id=1的管理员姓名为admin,密码为admin
UPDATE admin SET `password`="admin",username="admin"
WHERE id = 1

在这里插入图片描述


② 修改多表的记录:

语法:
sql99语法:
update1 别名 
left|right|inner join2 别名 
on 连接条件  
set 字段=,字段=值 
【where 筛选条件】;
练习一:
#案例1:修改张无忌的女朋友的手机号为114
UPDATE beauty b 
INNER JOIN boys bo
ON b.boyfriend_id = bo.id
SET phone = "114"
WHERE boyName = "张无忌"

在这里插入图片描述


练习二:

(我表中没有boyfriend_id为4的,之前删了)

#案例2:修改没有男朋友的女生的男朋友编号都为2号
UPDATE beauty b
LEFT JOIN boys bo
ON b.boyfriend_id = bo.id
SET boyfriend_id = 2
WHERE boyName IS NULL

在这里插入图片描述


(3) 删除 (delete)

① 删除单表的记录:

语法:
语法:delete from 表名 【where 筛选条件】【limit 条目数】
练习一:
#案例1:删除手机号以9结尾的女生信息
DELETE FROM beauty 
WHERE phone LIKE "%9" 

在这里插入图片描述


② 删除多表的记录:

语法:
(ps:delete后别名写哪个就删哪个表中,如果两个都写,两个表都删)
语法:
delete 别名1,别名2 from1 别名1 
inner|left|right join2 别名2 
on 连接条件
 【where 筛选条件】
练习一:
#案例1:删除张无忌的女朋友的信息
DELETE b FROM beauty b
INNER JOIN boys bo
ON b.boyfriend_id = bo.id
WHERE boyName = "张无忌"

编号为1的都被删除


练习二:
#案例2:删除黄晓明的信息以及他女朋友的信息
DELETE bo,b
FROM boys bo 
INNER JOIN beauty b
ON b.boyfriend_id = bo.id
WHERE boyName = "黄晓明"

在这里插入图片描述
在这里插入图片描述


③ 删除整个表 (truncate):

truncate:删除整个表,不能加where语句

删除整个boys表:
truncate table boys 
truncate 和 delete 的对比:
1.truncate删除后,如果再插入,标识列从1开始
  delete删除后,如果再插入,标识列从断点开始
  
2.delete可以添加筛选条件
 truncate不可以添加筛选条件
 
3.truncate效率较高

4.truncate没有返回值
  delete可以返回受影响的行数

5.truncate不可以回滚
  delete可以回滚

DDL 数据定义语言

(1) 库的管理

① 库的创建:

语法:
create databaseif not exists】 库名【 character set 字符集名】;
# 创建数据库 books
CREATE DATABASE IF NOT EXISTS books

在这里插入图片描述


② 库的修改:

语法:
alter database 库名 character set 字符集名;
# 修改数据库 books 的字符集 为gbk
ALTER DATABASE books CHARACTER SET gbk

在这里插入图片描述


③ 库的删除:

语法:
drop databaseif exists】 库名;
# 删除数据库 books
DROP DATABASE IF EXISTS books

(2) 表的管理

① 表的创建:

语法:
create tableif not exists】 表名(
	字段名 字段类型 【约束】,
	字段名 字段类型 【约束】,
	......
	字段名 字段类型 【约束】 
)
练习一:
#案例:创建表Book
CREATE TABLE book(
	id INT,#编号
	bName VARCHAR(20),#图书名
	price DOUBLE,#价格
	authorId  INT,#作者编号
	publishDate DATETIME#出版日期
);

在这里插入图片描述


练习二:
#案例:创建表author
CREATE TABLE IF NOT EXISTS author(
	id INT,
	au_name VARCHAR(20),
	nation VARCHAR(10)
)

在这里插入图片描述


② 表的修改:

语法:
alter table 表名 add|drop|modify|change column 列名 【列类型 约束】;
练习一 (修改列名):
#修改列名
ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;

在这里插入图片描述


练习二 (修改列的类型或约束):
#修改列的类型或约束
ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;

在这里插入图片描述


练习三 (添加新列):
#添加新列
ALTER TABLE author ADD COLUMN annual DOUBLE; 

在这里插入图片描述


练习四 (删除列):
#删除列
ALTER TABLE book_author DROP COLUMN  annual;

练习五 (修改表名):
#修改表名
ALTER TABLE author RENAME TO book_author

在这里插入图片描述


③ 表的删除:

语法:
DROP TABLE IF EXISTS book_author;

④ 表的复制:

先创建个表
INSERT INTO author VALUES
(1,'村上春树','日本'),
(2,'莫言','中国'),
(3,'冯唐','中国'),
(4,'金庸','中国');

在这里插入图片描述


练习一 (仅仅复制表的结构):
#仅仅复制表的结构
CREATE TABLE copy LIKE author

在这里插入图片描述


练习二 (复制表的结构+数据):
#复制表的结构+数据
CREATE TABLE copy1 SELECT * FROM author

在这里插入图片描述


练习三 (只复制部分数据):
#只复制部分数据:复制国家为中国的作家信息
CREATE TABLE copy2 
SELECT id,au_name
FROM author
WHERE nation = "中国"

在这里插入图片描述


练习四 (仅仅复制某些字段):
where 条件找不到值,所以只有字段
#只复制部分数据:复制国家为中国的作家信息
CREATE TABLE copy3
SELECT id,au_name
FROM author
WHERE 1>2

在这里插入图片描述


(3) 数据类型

① 数值型

整型

在这里插入图片描述

特点:
特点:
都可以设置无符号和有符号,默认有符号,通过unsigned设置无符号

如果超出了范围,会报out of range异常,插入临界值

长度可以不指定,默认会有一个长度

长度代表显示的最大宽度,如果不够则左边用0填充
但需要搭配zerofill,并且默认变为无符号整型

浮点型

特点:
特点:
M:代表整数部位+小数部位的个数
D:代表小数部位

如果超出范围,则报out of range异常,并且插入临界值

M和D都可以省略,但对于定点数,M默认为10,D默认为0

如果精度要求较高,则优先考虑使用定点数

② 字符型

在这里插入图片描述

特点:
char:固定长度的字符,写法为char(M)
最大长度不能超过M,其中M可以省略,默认为1

varchar:可变长度的字符,写法为varchar(M)
最大长度不能超过M,其中M不可以省略

③ 日期型

在这里插入图片描述

datetime和timestamp的区别

1Timestamp支持的时间范围较小,取值范围:
19700101080001——2038年的某个时间
Datetime的取值范围:1000-1-1 ——999912-31

2timestamp和实际时区有关,更能反映实际的日期
而datetime则只能反映出插入时的当地时区

3timestamp的属性受Mysql版本和SQLMode的影响很大

(4) 常见约束

① 约束的含义:

含义:一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性

② 约束的分类:

分类:六大约束
	NOT NULL:非空,用于保证该字段的值不能为空
	比如姓名、学号等
	
	DEFAULT:默认,用于保证该字段有默认值
	比如性别
	
	PRIMARY KEY:主键,用于保证该字段的值具有唯一性,并且非空
	比如学号、员工编号等
	
	UNIQUE:唯一,用于保证该字段的值具有唯一性,可以为空
	比如座位号
	
	CHECK:检查约束【mysql中不支持】
	比如年龄、性别
	
	FOREIGN KEY:外键,用于限制两个表的关系 【mysql中无效果】
	用于保证该字段的值必须来自于主表的关联列的值
	在从表添加外键约束,用于引用主表中某列的值
	比如学生表的专业编号,员工表的部门编号,员工表的工种编号

③ 约束的添加分类:

约束的添加分类:
	列级约束:
		六大约束语法上都支持,但外键约束没有效果
		
	表级约束:
		除了非空、默认,其他的都支持
		语法:在各个字段的最下面
 				【constraint 约束名】 约束类型(字段名) 


④ 添加约束的时机:

添加约束的时机:
	1.创建表时 
	2.修改表时

练习一:创建表 时添加 列级 约束
# 创建表 major
CREATE TABLE major(
	id INT PRIMARY KEY,
	majorName VARCHAR(20)
);


# 创建表 stuinfo
CREATE TABLE stuinfo(
	id INT PRIMARY KEY,#主键
	stuName VARCHAR(20) NOT NULL,#非空
	gender CHAR(1) CHECK(gender='男' OR gender ='女'),# mysql不支持
	seat INT UNIQUE,#唯一
	age INT DEFAULT  18,#默认约束
	majorId INT REFERENCES major(id)#外键 (mysql没效果)
);

# 展示字段信息
DESC stuinfo

在这里插入图片描述


练习二:创建表 时添加 列级 约束
DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1),
	seat INT,
	age INT,
	majorid INT,
	
	CONSTRAINT pk PRIMARY KEY(id),#主键
	CONSTRAINT uq UNIQUE(seat),#唯一键
	CONSTRAINT ck CHECK(gender ='男' OR gender  = '女'),#检查
	CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外键
	
);

练习三:修改表 时 添加和删除 (列级,表级)约束
语法:修改表时

添加 列级 约束
alter table 表名 modify column 字段名 字段类型 新约束;

添加 表级 约束
alter table 表名 addconstraint 约束名】 约束类型(字段名) 【外键的引用】;

创建表 stuinfo

DROP TABLE IF EXISTS stuinfo;
CREATE TABLE stuinfo(
	id INT,
	stuname VARCHAR(20),
	gender CHAR(1),
	seat INT,
	age INT,
	majorid INT
)
DESC stuinfo;

各种语句 参考

#1.添加非空约束
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20)  NOT NULL;

#2.添加默认约束
ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;

#3.添加主键
#①列级约束
ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;
#②表级约束
ALTER TABLE stuinfo ADD PRIMARY KEY(id);

#4.添加唯一
#①列级约束
ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;
#②表级约束
ALTER TABLE stuinfo ADD UNIQUE(seat);


#5.添加外键
ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major 
FOREIGN KEY(majorid) REFERENCES major(id); 



#---------------------修改表时删除约束--------------------------

#1.删除非空约束 (NULL可省略)
ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;

#2.删除默认约束
ALTER TABLE stuinfo MODIFY COLUMN age INT ;

#3.删除主键
ALTER TABLE stuinfo DROP PRIMARY KEY;

#4.删除唯一
ALTER TABLE stuinfo DROP INDEX seat;

#5.删除外键
ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;

SHOW INDEX FROM stuinfo;

⑤主键(primary key)和唯一(unique)的对比:

主键和唯一的对比:

		保证唯一性  是否允许为空    一个表中可以有多少个   是否允许组合
	主键	√			×			至多有1个           √,但不推荐
	唯一	√			√			可以有多个          √,但不推荐

⑥外键的定义和特点:

外键:
	1、要求在从表设置外键关系
	2、从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求
	3、主表的关联列必须是一个key(一般是主键或唯一)
	4、插入数据时,先插入主表,再插入从表
	删除数据时,先删除从表,再删除主表

(5) 标识列

标识列的含义和特点

#标识列
又称为自增长列
含义:可以不用手动的插入值,系统提供默认的序列值


特点:
1、标识列必须和主键搭配吗?不一定,但要求是一个key(比如pk和unique)

2、一个表可以有几个标识列?最多一个

3、标识列的类型只能是数值型

4、标识列可以通过 SET auto_increment_increment=3;设置步长
可以通过 手动插入值,设置起始值
练习一:

id 自增长

CREATE TABLE stuinfo(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20) NOT NULL
)

在这里插入图片描述

插入三条语句,只插入名字,但是编号自动排序了

INSERT INTO stuinfo(`name`)
VALUES("zhangsan"),
("lisi"),
("wangwu")

在这里插入图片描述

设置步长

SET auto_increment_increment=3;

重新建表,在插入这三条数据前就更改步长为3
在这里插入图片描述


(6) 事务

① 事务的含义:

一个或一组sql语句组成一个执行单元
这个执行单元要么全部执行,要么全部不执行。

② 事务的特性:

ACID
原子性:一个事务不可再分割,要么都执行要么都不执行

一致性:一个事务执行会使数据从一个一致状态切换到另外一个一致状态

隔离性:一个事务的执行不受其他事务的干扰

持久性:一个事务一旦提交,则会永久的改变数据库的数据.

③ 事务的创建:

隐式事务
隐式事务:事务没有明显的开启和结束的标记

比如insertupdatedelete语句
delete fromwhere id =1;

显式事务
显式事务:事务具有明显的开启和结束的标记
前提:必须先设置自动提交功能为禁用

set autocommit=0;

步骤1:开启事务
set autocommit=0;
start transaction;可选的

步骤2:编写事务中的sql语句(select insert update delete)
语句1;
语句2;
...

步骤3:结束事务
commit;提交事务
rollback;回滚事务

先建个测试表

CREATE TABLE test(
	id INT PRIMARY KEY,
	name VARCHAR(20),
	money INT 
)

INSERT INTO test
VALUES (1,"aaa",1000),
	   (2,"bbb",1000)

在这里插入图片描述


练习一:
# 步骤一:开启事务
SET autocommit=0;
START TRANSACTION;

# 步骤二:编写事务中的sql语句
UPDATE test SET money = 500 WHERE `name` = "aaa";
UPDATE test SET money = 1500 WHERE `name` = "bbb"; 

# 结束事务
ROLLBACK; # 回滚事务

SELECT * FROM test ;

在这里插入图片描述


练习二
# 步骤一:开启事务
SET autocommit=0;
START TRANSACTION;

# 步骤二:编写事务中的sql语句
UPDATE test SET money = 500 WHERE `name` = "aaa";
UPDATE test SET money = 1500 WHERE `name` = "bbb";

# 结束事务
COMMIT;

SELECT * FROM test ;

在这里插入图片描述


④ savepoint 设置保存点:

保存点 a 以前的操作不受影响,以后的操作 rollback

# 开启事务
SET autocommit = 0;
START TRANSACTION;

# 编写一组事务的语句
DELETE FROM test WHERE id = 1;
SAVEPOINT a;
DELETE FROM test WHERE id = 2;
ROLLBACK TO a;

SELECT * FROM test ; 

在这里插入图片描述


⑤ 事务的隔离级别:

在这里插入图片描述

事务隔离级别 脏读 不可重复读 幻读
read uncommitted
read committed ×
repeatable read × ×
serializable × × ×
mysql中默认 第三个隔离级别 repeatable read

oracle中默认第二个隔离级别 read committed

查看隔离级别
mysql 8.0以下:select @@tx_isolation;
mysql 8.0以上:SELECT @@transaction_isolation;

设置隔离级别
set session|global transaction isolation level 隔离级别;

在这里插入图片描述


(7) 视图

含义:虚拟表,和普通表一样使用
mysql5.1版本出现的新特性,是通过表动态生成的数据

① 视图的创建和使用:

练习一:
# 案例一:查询姓名中包含a字符的员工名,部门名和工种名

# 1 先创建视图
CREATE VIEW v1 
AS
SELECT last_name,department_name,job_title
FROM employees e
INNER JOIN jobs j ON e.job_id = j.job_id
INNER JOIN departments d ON d.department_id = e.department_id ;

# 2 使用视图
SELECT * FROM v1 WHERE last_name LIKE "%a%" ;

在这里插入图片描述


练习二:
# 案例:查询各部门的平均工资级别

# 1 创建视图:各部门的平均工资
CREATE VIEW v2
AS
SELECT department_id,AVG(salary) ag
FROM employees
GROUP BY department_id;

# 2:使用视图
SELECT v2.ag,grade_level
FROM v2 
INNER JOIN job_grades j
ON v2.ag BETWEEN j.lowest_sal AND j.highest_sal;

在这里插入图片描述


练习三:
# 案例:查询平均工资最低的部门id

# 直接使用视图v2
SELECT * 
FROM v2
ORDER BY v2.ag ASC
LIMIT 1

在这里插入图片描述


练习四:
# 案例:查询平均工资最低的部门名和工资

# 创建视图:
CREATE VIEW v3
AS
SELECT department_name,v2.ag
FROM v2
INNER JOIN departments d
ON v2.department_id = d.department_id ;

# 使用视图v3
SELECT * 
FROM v3 
ORDER BY v3.ag ASC
LIMIT 1

在这里插入图片描述


② 视图的修改:

方式一:
create or replace view  视图名
as
查询语句;



方式二:
alter view 视图名
as 
查询语句;

练习 alter 修改视图:
ALTER VIEW v3
AS 
SELECT * FROM employees

再次查询 v3 :
在这里插入图片描述


③ 视图的查看和删除:

练习一 查看视图:
语法
DESC 视图名;

SHOW CREATE VIEW 视图名;

DESC v3;

在这里插入图片描述


练习二 删除视图:
语法:drop view 视图名,视图名,...;

DROP VIEW v1,v3 ;

在这里插入图片描述


④ 视图的更新 (视图主要是用来查询,而不是更新):

新建一个视图用以测试

CREATE VIEW v1
AS 
SELECT last_name,salary 
FROM employees 

更新的语句和表的基本一样

练习一 (插入):
INSERT INTO v1 VALUES("xxx",9999)

在这里插入图片描述


练习二 (修改):
UPDATE v1 SET salary = 9999 WHERE last_name = "K_ing"

在这里插入图片描述


练习三 (删除):
DELETE FROM v1 WHERE last_name = "xxx"

在这里插入图片描述


⑤ 视图不允许被更新的情况

1:包含以下关键字的sql语句:分组函数、distinct
group  byhavingunion或者union all

2:常量视图

3Select中包含子查询

4join

5from一个不能更新的视图

6where子句的子查询引用了from子句中的表

⑥ 视图和表的对比

创建语法的关键字 是否实际占用物理空间 使用
视图 create view 只是保存了sql逻辑 增删改查,只是一般不能增删改
create table 保存了数据 增删改查

(8) 变量

① 变量的分类:

系统变量:
	全局变量
	会话变量

自定义变量:
	用户变量
	局部变量

② 系统变量:

说明:变量由系统定义,不是用户定义,属于服务器层面

注意:全局变量需要添加global关键字,会话变量需要添加session关键字
如果不写,默认会话(session)级别

使用步骤:
1、查看所有系统变量
show global|session】variables;

2、查看满足条件的部分系统变量
show global|session】 variables like '%char%';

3、查看指定的系统变量的值
select @@global|session】系统变量名;

4、为某个系统变量赋值
方式一:
set global|session】系统变量名=;

方式二:
set @@global|session】系统变量名=;

全局变量

作用域:针对于所有会话(连接)有效,但不能跨重启

#查看所有全局变量
SHOW GLOBAL VARIABLES;

#查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';

#查看指定的系统变量的值
SELECT @@global.autocommit;

#④为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;

会话变量

作用域:针对于当前会话(连接)有效

#查看所有会话变量
SHOW SESSION VARIABLES;

#查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%char%';

#查看指定的会话变量的值
SELECT @@autocommit;
mysql8.0以下
SELECT @@session.tx_isolation;
mysql8.0以上
SELECT @@session.TRANSACTION_isolation;

#为某个会话变量赋值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';

③ 自定义变量:

说明:变量由用户自定义,而不是系统提供的

使用步骤:
1、声明
2、赋值
3、使用(查看、比较、运算等)

用户变量

作用域:针对于当前会话(连接)有效,作用域同于会话变量

#赋值操作符:=或:=
#声明并初始化
SET @变量名=;
SET @变量名:=;
SELECT @变量名:=;

#赋值(更新变量的值)
#方式一:
	SET @变量名=;
	SET @变量名:=;
	SELECT @变量名:=;
#方式二:
	SELECT 字段 INTO @变量名
	FROM;
	
#使用(查看变量的值)
SELECT @变量名;

练习
SET @a=10;
SET @b=20;

SET @sum=@a+@b;

SELECT @sum;

在这里插入图片描述


局部变量

作用域:仅仅在定义它的begin end块中有效

应用在 begin end中的第一句话

#声明
DECLARE 变量名 类型;
DECLARE 变量名 类型 【DEFAULT 值】;

#赋值(更新变量的值)

#方式一:
	SET 局部变量名=;
	SET 局部变量名:=;
	SELECT 局部变量名:=;
#方式二:
	SELECT 字段 INTO 具备变量名
	FROM;
	
#使用(查看变量的值)
SELECT 局部变量名;

④ 用户变量和局部变量的对比

作用域 定义位置 语法
用户变量 当前会话 会话的任何地方 加@符号,不用指定类型
局部变量 定义它的BEGIN END中 BEGIN END的第一句话 一般不用加@,需要指定类型

(9) 存储过程

① 存储过程的含义和好处:

含义:一组预先编译好的SQL语句的集合,理解成批处理语句

好处:
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率

② 创建语法:

CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
	存储过程体(一组合法的SQL语句)
END


1、参数列表包含三部分
	  参数模式  参数名  参数类型
举例: in   stuname   varchar(20)


参数模式:
in:该参数可以作为输入,也就是该参数需要调用方传入值
out:该参数可以作为输出,也就是该参数可以作为返回值
inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值
又可以返回值

2、如果存储过程体仅仅只有一句话,begin end可以省略
存储过程体中的每条sql语句的结尾要求必须加分号。
存储过程的结尾可以使用 delimiter 重新设置
语法:
delimiter 结束标记
案例:
delimiter $

③ 调用语法:

CALL 存储过程名(实参列表);

练习一 (空参列表):
#案例:插入到admin表中五条数据
# 创建存储过程
CREATE PROCEDURE p1()
BEGIN 
		INSERT INTO admin
		VALUES(3,"333","333"),
			  (4,"444","444"),
			  (5,"555","555");
END;

# 调用p1
CALL p1();

在这里插入图片描述


练习二 (带 in 参数):
#案例:创建存储过程实现 根据女生名,查询对应的男生信息
# 创建存储过程
CREATE PROCEDURE p2(IN beautyName VARCHAR(20))
BEGIN
		SELECT bo.*
		FROM boys bo
		RIGHT JOIN beauty b
		ON bo.id = b.boyfriend_id 
		WHERE b.`name` = beautyName;
END;

# 调用p2
CALL p2('小昭');

在这里插入图片描述


#案例:创建存储过程实现,用户是否登录成功(admin表)
# 创建存储过程
CREATE PROCEDURE p3(IN username VARCHAR(20),IN password VARCHAR(20))
BEGIN
		DECLARE result INT DEFAULT 0; # 声明变量result
		
		SELECT COUNT(*) INTO result
		FROM admin
		WHERE admin.username = username 
		AND admin.password = password;
		
		SELECT IF(result>0,"登录成功","登陆失败");
END;

# 调用p3
CALL p3('john',8888);

在这里插入图片描述


练习三 (带 out 参数):
#案例:根据输入的女生名,返回对应的男朋友名
# 创建存储过程
CREATE PROCEDURE p4(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20))
BEGIN
		SELECT bo.boyName INTO boyName
		FROM boys bo
		INNER JOIN beauty b
		ON bo.id = b.boyfriend_id
		WHERE b.`name` = beautyName;
		
END;


# 调用p4
SET @result='';
CALL p4('小昭',@result);
SELECT @result;

在这里插入图片描述


练习四 (带 inout 参数):
#案例:传入a和b两个值,最终a和b都翻倍并返回
# 创建存储过程
CREATE PROCEDURE p5(INOUT a INT,INOUT b INT)
BEGIN
		SET a = a*2;
		SET b = b*2;
END;

# 调用p5
SET @x=10;
SET @y=20;
CALL p5(@x,@y);
SELECT @x,@y;

在这里插入图片描述


④ 删除存储过程

DROP PROCEDURE 存储过程;

示例:
DROP PROCEDURE p2;

⑤ 查看存储过程

SHOW CREATE PROCEDURE 存储过程;

示例:
SHOW CREATE PROCEDURE p1;

在这里插入图片描述


(10) 函数

和存储过程相似

含义:一组预先编译好的SQL语句的集合,理解成批处理语句

好处:
1、提高代码的重用性
2、简化操作
3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率

① 函数与存储过程的区别:

存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新

函数:有且仅有1 个返回,适合做处理数据后返回一个结果

② 创建语法:

CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型
BEGIN
	函数体
END



注意:
1.参数列表 包含两部分:
参数名 参数类型

2.函数体:肯定会有return语句,如果没有会报错
如果return语句没有放在函数体的最后也不报错,但不建议

return;
3.函数体中仅有一句话,则可以省略begin end

4.使用 delimiter语句设置结束标记

③ 调用语法:

SELECT 函数名(参数列表)

报错 This function has none of DETERMINISTIC, NO SQL…:解决

set global log_bin_trust_function_creators=TRUE;

如果mysqld重启,那个参数又会消失,因此记得在my.cnf配置文件中添加:
log_bin_trust_function_creators=1

练习一 (无参有返回):
#案例:返回公司的员工个数
CREATE FUNCTION f1() RETURNS INT
BEGIN
			DECLARE sum INT; #局部变量
			
			SELECT COUNT(*) INTO sum #赋值
			FROM employees;
			
			RETURN sum; #返回
END;

SELECT f1();

在这里插入图片描述


练习二 (有参有返回):
#案例1:根据员工名,返回它的工资
CREATE FUNCTION f2(name VARCHAR(20)) RETURNS DOUBLE
BEGIN	
			SET @s=0; #定义用户变量
			
			SELECT salary INTO @s #赋值
			FROM employees
			WHERE last_name = name;
			
			RETURN @s; #返回
END;

SELECT f2("Kochhar");

在这里插入图片描述


#案例2:根据部门名,返回该部门的平均工资
CREATE FUNCTION f3(id INT) RETURNS DOUBLE
BEGIN
			DECLARE s DOUBLE;
			
			SELECT AVG(salary) INTO s
			FROM employees
			WHERE department_id = id;
			
			RETURN s;
END;

SELECT f3(90);

在这里插入图片描述


④ 查看函数

SHOW CREATE FUNCTION 函数;

示例:
SHOW CREATE FUNCTION f3;

在这里插入图片描述


⑤ 删除函数

DROP FUNCTION 函数;

示例:
DROP FUNCTION f3;

(11) 流程控制结构

---------分支结构---------

① case 结构

语法和应用范围:
语法:
情况1:类似于switch
case 变量或表达式
when1 then 语句1;
when2 then 语句2;
...
else 语句n;
end 


情况2case 
when 条件1 then 语句1;
when 条件2 then 语句2;
...
else 语句n;
end 


应用在begin end 中或外面 (任何地方)

② if 结构:

语法和应用范围:
语法:
if 条件1 then 语句1;
elseif 条件2 then 语句2;
....
else 语句n;
end if;
功能:类似于多重if


只能应用在begin end

练习一 (if 结构):
#案例:创建函数,实现传入成绩,如果成绩>90,返回A
#如果成绩>80,返回B,如果成绩>60,返回C,否则返回D

CREATE FUNCTION t_if(score INT) RETURNS CHAR
BEGIN
			IF score>90 AND score<=100 THEN RETURN 'A';
			ELSEIF score>80 THEN RETURN 'B';
			ELSEIF score>60 THEN RETURN 'C';
			ELSE RETURN 'D';
			END IF ;
END;


SELECT t_if(85);

在这里插入图片描述


练习二 (if结构):
#案例:创建存储过程,如果工资<2000,则删除
#如果5000>工资>2000,则涨工资1000,否则涨工资500
CREATE PROCEDURE p_if(IN sal DOUBLE)
BEGIN
			IF sal<2000 THEN DELETE FROM employees WHERE salary=sal;
			ELSEIF sal>2000 AND sal<5000 
					THEN 
					UPDATE employees 
					SET salary=salary+1000 
					WHERE salary=sal;
			ELSE  
					UPDATE employees 
					SET salary=salary+500 
					WHERE salary=sal;
			END IF;
END;

CALL p_if(2100);

2100元的人涨了1000元
在这里插入图片描述
在这里插入图片描述


练习三 (case结构):
#案例:创建函数,实现传入成绩,如果成绩>90,返回A
#如果成绩>80,返回B,如果成绩>60,返回C,否则返回D

CREATE FUNCTION t_case(score INT) RETURNS CHAR
BEGIN
			CASE	
			WHEN score>90 AND score<=100 THEN RETURN 'A';
			WHEN score>80 THEN RETURN 'B';
			WHEN score>60 THEN RETURN 'C';
			ELSE RETURN 'D';
			END CASE;
END;

SELECT t_case(95);

在这里插入图片描述


---------循环结构---------

① 分类

分类:
whilelooprepeat

② 循环控制:

iterate类似于 continue,继续,结束本次循环,继续下一次

leave 类似于  break,跳出,结束当前所在的循环

③ 语法:

在这里插入图片描述


练习一 (没有添加循环控制语句):
#批量插入,根据次数插入到admin表中多条记录
CREATE PROCEDURE p_while(IN cnt INT)
BEGIN
			DECLARE i INT DEFAULT 0;
			WHILE i<cnt DO
					INSERT INTO admin(username,password)  #插入语句
					VALUES(CONCAT("ttt",i),111);
					
					SET i=i+1; #i++
			
			END WHILE;
END;

CALL p_while(10);

在这里插入图片描述


练习二 (添加 leave 语句):
#案例:批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止
CREATE PROCEDURE t_while1(IN cnt INT)
BEGIN 
			SET @i=0; #定义局部变量
			
			a:WHILE @i<cnt DO  #循环插入
					INSERT INTO admin(username,`password`) 
					VALUES(CONCAT("xxx",@i),222);
					
					SET @i=@i+1; #i++
					
					IF @i=20 THEN LEAVE a; #当i=20,结束循环
					END IF; 
					
			END WHILE a;
END;

# 测试插入100条数据,实则插入20条就停止
CALL t_while1(100);

在这里插入图片描述


练习三 (添加 iterate 语句):
#案例:批量插入,根据次数插入到admin表中多条记录,只插入偶数次
CREATE PROCEDURE t_while2(IN cnt INT)
BEGIN
		DECLARE i INT DEFAULT -1;
			
		a:WHILE i<cnt DO
				SET i=i+1; #i++
				
				IF MOD(i,2)=1 THEN ITERATE a; #如果为奇数次,则跳过
				END IF;
				
				INSERT INTO admin(username,`password`) #偶数次则插入
				VALUES(CONCAT("bbb",i),333);
				
			END WHILE a;					
END;

CALL t_while2(20);

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45260385/article/details/114047703