MySQL语法大全

MySQL基础

文章目录

本单元目标

一、为什么要学习数据库
二、数据库的相关概念      
	DBMS、DB、SQL
三、数据库存储数据的特点
四、初始MySQL
	MySQL产品的介绍        
	MySQL产品的安装          ★        
	MySQL服务的启动和停止     ★
	MySQL服务的登录和退出     ★      
	MySQL的常见命令和语法规范      
五、DQL语言的学习   ★              
	基础查询        ★             
	条件查询  	   ★			
	排序查询  	   ★				
	常见函数        ★               
	分组函数        ★              
	分组查询		   ★			
	连接查询	 	★			
	子查询       √                  
	分页查询       ★              
	union联合查询	√			
	
六、DML语言的学习    ★             
	插入语句						
	修改语句						
	删除语句						
七、DDL语言的学习  
	库和表的管理	 √				
	常见数据类型介绍  √          
	常见约束  	  √			
八、TCL语言的学习
	事务和事务处理                 
九、视图的讲解           √
十、变量                      
十一、存储过程和函数   
十二、流程控制结构       

数据库的好处

1.持久化数据到本地
2.可以实现结构化查询,方便管理

数据库相关概念

1、DB:数据库,保存一组有组织的数据的容器
2、DBMS:数据库管理系统,又称为数据库软件(产品),用于管理DB中的数据
3、SQL:结构化查询语言,用于和DBMS通信的语言

数据库存储数据的特点

1、将数据放到表中,表再放到库中
2、一个数据库中可以有多个表,每个表都有一个的名字,用来标识自己。表名具有唯一性。
3、表具有一些特性,这些特性定义了数据在表中如何存储,类似java中 “类”的设计。
4、表由列组成,我们也称为字段。所有表都是由一个或多个列组成的,每一列类似java 中的”属性”
5、表中的数据是按行存储的,每一行类似于java中的“对象”。

MySQL产品的介绍和安装

MySQL服务的启动和停止

方式一:计算机——右击管理——服务
方式二:通过管理员身份运行
net start 服务名(启动服务)
net stop 服务名(停止服务)

MySQL服务的登录和退出

方式一:通过mysql自带的客户端
只限于root用户

方式二:通过windows自带的客户端
登录:
mysql 【-h主机名 -P端口号 】-u用户名 -p密码
例如:mysql -hlocalhost -p3306 -uroot -p123
例如:mysql -uroot -p123

退出:
exit或ctrl+C

MySQL的常见命令

1.查看当前所有的数据库
show databases;

2.打开指定的库
use 库名

3.查看当前库的所有表
show tables;

4.查看其它库的所有表
show tables from 库名;

5.创建表
create table 表名(

	列名 列类型,
	列名 列类型,
	。。。
);

6.查看表结构
desc 表名;


7.查看服务器的版本
方式一:登录到mysql服务端
select version();
方式二:没有登录到mysql服务端
mysql --version
或
mysql --V

MySQL的语法规范

1.不区分大小写,但建议关键字大写,表名、列名小写
2.每条命令最好用分号结尾
3.每条命令根据需要,可以进行缩进或换行
4.注释
	单行注释:#注释文字
	单行注释:-- 注释文字
	多行注释:/* 注释文字  */

SQL的语言分类

DQL(Data Query Language):数据查询语言
	select 
DML(Data Manipulate Language):数据操作语言
	insert 、update、delete
DDL(Data Define Languge):数据定义语言
	create、drop、alter
TCL(Transaction Control Language):事务控制语言
	commit、rollback

SQL的常见命令

show databases; 查看所有的数据库

use 库名; 打开指定 的库

show tables ; 显示库中的所有表

show tables from 库名;显示指定库中的所有表

create table 表名(
	字段名 字段类型,	
	字段名 字段类型
); 创建表

desc 表名; 查看指定表的结构

select * from 表名;显示表中的所有数据

DQL语言的学习

进阶1:基础查询

语法:
SELECT 要查询的东西
【FROM 表名】;

特点:
①通过select查询完的结果 ,是一个虚拟的表格,不是真实存在
② 要查询的东西 可以是常量值、可以是表达式、可以是字段、可以是函数

起别名

起别名方式一:使用AS,如果别名有关键字,可以加双引号
例如:

 SELECT 
	 last_name AS 姓氏,
	 first_name AS 名字,
	 email AS 邮件地址,
	 job_id AS 工作编号 
 FROM 
 	employees;

起别名方式二:使用空格,如果别名有关键字,可以加双引号
例如:

SELECT
 	last_name 姓氏,
 	first_name 名字,
	 email 邮件地址,
	 job_id 工作编号
 FROM 
	 employees;

去重

加关键字 distinct

SELECT DISTINCT 
	job_id
FROM 
	employees;
拼接字段和ifnull 函数

加拼接函数 concat,如果拼接的字段中有NULL的情况,则拼接的结果为null
此时可以加一个 ifnull 函数判断是否为NULL

SELECT
	CONCAT(last_name, first_name) AS 姓名
FROM
	employees;
SELECT
	CONCAT(
		last_name,
		'/',
		first_name,
		'/',
		IFNULL(commission_pct, 0)
	) AS 输出结果
FROM
	employees;
isnull函数
如果为null则返回1,否则返回0

进阶2:条件查询

条件查询:根据条件过滤原始表的数据,查询到想要的数据
语法:
select 
	要查询的字段|表达式|常量值|函数
from 
	表
where 
	条件 ;

分类:

一、条件表达式
	示例:salary>10000
	条件运算符:
	> < >= <= = != <>
二、逻辑表达式
示例:salary>10000 && salary<20000

逻辑运算符:
and(&&):两个条件如果同时成立,结果为true,否则为false
or(||):两个条件只要有一个成立,结果为true,否则为false
not(!):如果条件成立,则not后为false,否则为true

三、模糊查询
	like  ---->判断是否包含,可以判断字符型或数值型
	between and  --->判断在什么区间内
	in  ---->判断在不在条件内
	is null  --->判断是否为NULL
	is not null  --->判断不为NULL
	<=>   ---->安全等于
	
% 是通配符,包含任意0个或多个字符
_ 是通配符,包含任意单个字符

示例1:like查询名字里包含aa的员工的全部信息

SELECT
	*
FROM
	employees
WHERE
	last_name LIKE ('%aa%');

示例2:between and查询员工编号在100到120的所有信息

SELECT
	*
FROM
	employees
WHERE
	employee_id BETWEEN 100 AND 120;

示例3:in 查询工种编号为’AD_VP’或’AD_PRES’的员工名字和工种编号

SELECT
	last_name,job_id
FROM
	employees
WHERE
	job_id in('AD_VP','AD_PRES');

示例4:is null查询没有奖金的员工名,等于号不能用于判断NULL,故要用is判断

SELECT 
	last_name
FROM 
	employees
WHERE
	commission_pct IS NULL;

示例5:is not null 查询有奖金的员工名

SELECT 
	last_name
FROM 
	employees
WHERE
	commission_pct IS NOT NULL;

示例6:安全等于 <=>,可以判断NULL和普通的等于

SELECT 
	last_name
FROM 
	employees
WHERE
	commission_pct <=> NULL;

进阶3:排序查询

语法:
select
	要查询的东西
from
	表
where 
	条件
order by 
	排序的字段|表达式|函数|别名 【asc|desc】

asc:升序   desc:降序
如果不写,默认是升序
order by后支持字段别名,一般放在语句的最后面,limit子句除外

示例一:

SELECT
	*
FROM
	employees
ORDER BY
	salary DESC

示例二:多个字段排序

SELECT
	*
FROM
	employees
ORDER BY
	employee_id DESC,
	salary DESC;

进阶4:常见函数

一、单行函数
1、字符函数
	concat  拼接
	substr  截取子串,索引从1开始
	instr  返回子串第一次出现的索引,如果找不到返回0
	upper  转换成大写
	lower  转换成小写
	trim  去前后指定的空格和字符
	ltrim  去左边空格
	rtrim  去右边空格
	replace  替换
	lpad  用指定字符进行左填充规定的字符长度
	rpad  用指定字符进行右填充规定的字符长度
	length  获取字节个数
	
2、数学函数
	round  四舍五入
	rand  随机数
	floor  向下取整
	ceil  向上取整
	mod  取余
	truncate  截断,小数点后保留几位
	
3、日期函数
	now  当前系统日期+时间
	curdate  当前系统日期
	curtime  当前系统时间
	str_to_date  将字符转换成日期,解析字符
	date_format  将日期转换成字符
	
4、流程控制函数
	a、if   处理双分支:SELECT IF (10<5, '大于', ' 小于');
	b、case语句  处理多分支
		case:要判断的字段或表达式
		when 常量1 then 要显示的表达式或语
		when 常量2 then 要显示的表达式或语句
		。。。
		else 显示默认情况
		end
		
5、其他函数
	version  版本
	database  当前库
	user  当前连接用户

在这里插入图片描述

二、分组函数,也称为统计函数,聚合函数,组函数
	sum 求和
	max 最大值
	min 最小值
	avg 平均值
	count 计数,一般count(*)用作统计行数

	特点:
	1、以上五个分组函数都忽略null值,除了count(*)
	2、sum和avg一般用于处理数值型
		max、min、count可以处理任何数据类型
    3、都可以搭配distinct使用,用于统计去重后的结果
	4、count的参数可以支持:
		字段、*、常量值,一般放1

	   建议使用 count(*)

进阶5:分组查询

语法:
select 查询的字段,分组函数
from 表
【where 条件】
group by 分组的字
【having 分组后的条件】
特点:
1、可以按单个字段分组
2、和分组函数一同查询的字段最好是分组后的字段
3、分组筛选
		     针对的表	       位置			关键字
分组前筛选:	  原始表		group by的前面		 where
分组后筛选: 分组后的结果集	  group by的后面	   having

4、可以按多个字段分组,字段之间用逗号隔开
5、可以支持排序
6、group by,having后可以支持别名

示例1:

SELECT
	AVG(salary),
	job_id
FROM
	employees
GROUP BY
	job_id;

示例2:添加条件的分组查询

SELECT
	AVG(salary),
	email,
	department_id
FROM
	employees
WHERE
	email LIKE '%a%'
GROUP BY
	department_id;

示例3:添加分组后的查找,添加having关键词

#查询每个部门的员工数
#筛选员工数大于2的部门
SELECT
	COUNT(*),
	department_id
FROM
	employees
GROUP BY
	department_id
HAVING COUNT(*)>2;

进阶6:多表连接查询

一、按年代划分
sql92标准:仅仅支持内连接,【不推荐使用】
sql99标准:支持内连接、外连接(不支持全外连接)、交叉连接,【推荐】

sql99标准语法:通过join关键字实现连接

含义:1999年推出的sql语法
支持:
	内连接 (inner)
	外连接
		左外连接 (left outer)
		右外连接 (right outer)
		全外连接 (full outer),mysql不支持
	交叉连接 (cross)

语法:
select 字段,...
from 表1
【inner|left outer|right outer|cross】join 表2 on  连接条件
【inner|left outer|right outer|cross】join 表3 on  连接条件
【where 筛选条件】
【group by 分组字段】
【having 分组后的筛选条件】
【order by 排序的字段或表达式】

好处:语句上,连接条件和筛选条件实现了分离,简洁明了!

二、按功能分类
内连接:
	等值连接
	非等值连接
	自连接
外连接:
	左外连接
	右外连接
	全外连接
交叉连接
三、等值连接——非等值连接
等值连接特点:
1.等值连接的结果 是 多个表的交集
2.n表连接,至少需要n-1个连接条件
3.多个表不分主次,没有顺序要求
4.一般为表起别名,提高阅读性和性能

非等值连接特点:
1.不用 = 进行连接,可能是大于小于等

示例1:等值连接

#sql92标准
SELECT 
	name,
	boyName
FROM
	boys,
	beauty
WHERE
	beauty.boyfriend_id=boys.id;

#sql99标准
SELECT 
	name,
	boyName
FROM 
	boys
inner join beauty on beauty.boyfriend_id=boys.id;

#sql99标准,三表连接
SELECT
	last_name,
	department_name,
	job_title
FROM
	employees e
INNER JOIN departments d ON e.department_id = d.department_id
INNER JOIN jobs j ON e.job_id = j.job_id
ORDER BY
	department_name ASC

示例2:非等值连接

#sql92标准
SELECT 
	salary,
	grade_level
FROM 
	employees e,
	job_grades g
WHERE 
	salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
	
#sql99标准
SELECT 
	salary,
	grade_level
FROM
	employees e,
INNER JOIN job_grades g ON e.salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
四、自连接
自连接特点:
   1.只涉及单表的本身
   2.不是所有的单表都能自连接
   3.将单表当成两张表甚至更多的表使用
#案例:查询 员工名和上级的名称
#sql92标准
SELECT 
	#e.employee_id,
	e.last_name,
	#m.employee_id,
	m.last_name
FROM 
	employees e,
	employees m
WHERE 
	e.`manager_id`=m.`employee_id`;

#sql99标准
SELECT
	e.last_name,
	m.last_name
FROM
	employees e
INNER JOIN employees m ON e.manager_id=m.employee_id;
五、外连接

外连接的应用场景:用于查询一个表中有,另一个表中没有的记录

特点:1、外连接的查询结果为主表中的所有记录
	       如果从表中有和它匹配的,则显示匹配的值
	       如果从表中没有和它匹配的,则显示null
	       外连接查询结果=内连接结果+主表中有而从表没有的记录
 2、左外连接,left join左边的是主表
    右外连接,right join右边的是主表
 3、左外和右外交换两个表的顺序,可以实现同样的效果 
 4、全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的

示例1:左外连接

#左外连接
 SELECT
	beauty.*, boys.*
FROM
	boys
LEFT OUTER JOIN beauty ON beauty.`boyfriend_id` = boys.`id`
WHERE
	boys.`id` IS NULL;

示例2:右外连接

#右外连接
 SELECT
	beauty.*, boys.*
FROM
	beauty
RIGHT OUTER JOIN boys ON beauty.`boyfriend_id` = boys.`id`
WHERE
	boys.`id` IS NULL;

示例3:MySql不支持全外连接

#语法:
 SELECT 
	b.*,bo.*
 FROM 
 	beauty b
 FULL OUTER JOIN boys bo ON b.`boyfriend_id` = bo.id;
六、交叉连接
#特点:是笛卡尔乘积的结果,两表相乘

#交叉连接
SELECT
	b.*, bo.*
FROM
	beauty b
CROSS JOIN boys bo;

进阶7:子查询

含义:

一条其他语句中又嵌套了另一条完整的select语句,其中被嵌套的select语句,称为子查询或内查询
在外面的查询语句,称为主查询或外查询

特点:

1、子查询都放在小括号内
2、子查询可以放在from后面、select后面、where后面、having后面,但一般放在条件的右侧
3、子查询优先于主查询执行,主查询使用了子查询的执行结果
4、子查询根据查询结果的行数不同分为以下两类:
① 单行子查询
	结果集只有一行
	一般搭配单行操作符使用:> < = <> >= <= 
	非法使用子查询的情况:
	a、子查询的结果为一组值
	b、子查询的结果为空
	
② 多行子查询
	结果集有多行
	一般搭配多行操作符使用:any、all、in、not in
	in: 属于子查询结果中的任意一个就行
	any和all往往可以用其他查询代替

分类:

按子查询出现的位置:
	select后面:
		   仅仅支持标量子查询	
	from后面:
		   支持表子查询	
	where或having后面:★
		   标量子查询(单行) √
		   列子查询  (多行) √	
		   行子查询	(用的较少)	
	exists后面(相关子查询)
		   表子查询
		
按结果集的行列数不同:
	标量子查询(结果集只有一行一列)
	列子查询(结果集只有一列多行)
	行子查询(结果集有一行多列)
	表子查询(结果集一般为多行多列)

一、where或having后面

标量子查询(单行子查询)
列子查询 (多行子查询)
行子查询 (用的较少)

示例1:标量子查询

#单重条件
SELECT
	*
FROM
	employees
WHERE
	salary > (
		SELECT
			salary
		FROM
			employees
		WHERE
			last_name = 'Abel'
	)
	
#多重条件
SELECT
		last_name,
		job_id,
		salary
	FROM
		employees
	WHERE
		job_id = (
			SELECT
				job_id
			FROM
				employees
			WHERE
				employee_id = 141
		)
	AND salary > (
		SELECT
			salary
		FROM
			employees
		WHERE
			employee_id = 143
	);
	
#外加having和group的
SELECT
	department_id,
	MIN(salary)
FROM
	employees
GROUP BY
	department_id
HAVING
	MIN(salary) > (
		SELECT
			MIN(salary)
		FROM
			employees
		WHERE
			department_id = 50
	);

示例2:列子查询

#IN
SELECT
	last_name
FROM
	employees
WHERE
	department_id IN (
		SELECT
			department_id
		FROM
			departments
		WHERE
			location_id IN (1400, 1700)
	);
	
	# ANY|SOME 相当于 MIN()
	# ALL 相当于 MAX()

在这里插入图片描述

示例3:行子查询

#查询员工编号最小并且工资最高的员工信息
SELECT
	*
FROM
	employees
WHERE
	(employee_id, salary) = (
		SELECT
			MIN(employee_id),
			MAX(salary)
		FROM
			employees
	);
二、在select后面

仅仅支持标量子查询

#案例:查询每个部门的员工个数
SELECT
	d.*, (
		SELECT
			COUNT(*)
		FROM
			employees e
		WHERE
			e.department_id = d.`department_id`
	) 个数
FROM
	departments d;


三、from后面:

​ 支持表子查询

#案例:查询每个部门的平均工资的工资等级
SELECT
	ag_dep.*, g.`grade_level`
FROM
	(
		SELECT
			AVG(salary) ag,
			department_id
		FROM
			employees
		GROUP BY
			department_id
	) ag_dep
INNER JOIN job_grades g ON ag_dep.ag BETWEEN lowest_sal
AND highest_sal;
四、exists后面(相关子查询)

​ 支持表子查询

​ 最终结果只有1和0

可以用 in 代替

/*
语法:
exists(完整的查询语句)
结果:
1或0
*/

SELECT
	bo.*
FROM
	boys bo
WHERE
	NOT EXISTS (
		SELECT
			boyfriend_id
		FROM
			beauty b
		WHERE
			bo.`id` = b.`boyfriend_id`
	);

进阶8:分页查询 limit

应用场景:

当要显示的数据,一页显示不全,需要分页提交sql请求
实际的web项目中需要根据用户的需求提交对应的分页查询的sql语句

语法:

select 字段|表达式,...
from 表
【where 条件】
【group by 分组字段】
【having 条件】
【order by 排序的字段】
limit 【起始的条目索引,】条目数;

特点:

1.起始条目索引从0开始

2.limit子句放在查询语句的最后

3.公式:select * from  表 limit (page-1)*sizePerPage,sizePerPage
假如:
每页显示条目数sizePerPage
要显示的页数 page

示例:

#显示前5条员工的信息
SELECT
	*	
FROM
	employees
LIMIT 0,5

#有奖金的员工信息,并且工资较高的前10名显示出来
SELECT
	*
FROM
	employees
WHERE
	commission_pct IS NOT NULL
ORDER BY
	salary DESC
LIMIT 10;

进阶9:联合查询 union

引入:
union 联合、合并,默认去重

应用场景:
要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时

语法:

select 字段|常量|表达式|函数 【from 表】 【where 条件】 
union 【all】
select 字段|常量|表达式|函数 【from 表】 【where 条件】 
union 【all】
select 字段|常量|表达式|函数 【from 表】 【where 条件】 
union  【all】
.....
select 字段|常量|表达式|函数 【from 表】 【where 条件】

特点:

1、多条查询语句的查询的列数必须是一致的
2、多条查询语句的查询的列的类型几乎相同
3、union代表去重,union all代表不去重
#案例:查询中国用户中男性的信息以及外国用户中年男性的用户信息
SELECT
	id,
	cname
FROM
	t_ca
WHERE
	csex = '男'
UNION ALL
	SELECT
		t_id,
		tname
	FROM
		t_ua
	WHERE
		tGender = 'male';

DML语言

数据操作语言:
插入:insert
修改:update
删除:delete

一、插入

语法:
insert into 表名(字段名,…)
values(值1,…);

特点:

1、字段类型和值类型一致或兼容,而且一一对应
2、可以为空的字段,可以不用插入值,或用null填充
3、不可以为空的字段,必须插入值
4、字段个数和值的个数必须一致
5、字段可以省略,但默认所有字段,并且顺序和表中的存储顺序一致
#方式一:经典的插入

/*
语法:
insert into 表名(列名,...) values(值1,...);

*/

#1.插入的值的类型要与列的类型一致或兼容
INSERT INTO beauty (
	id,
	NAME,
	sex,
	borndate,
	phone,
	photo,
	boyfriend_id
)
VALUES
	(
		13,
		'唐艺昕',
		'女',
		'1990-4-23',
		'1898888888',
		NULL,
		2
	);

#2.不可以为null的列必须插入值。可以为null的列如何插入值?
#方法一:
INSERT INTO beauty (
	id,
	NAME,
	sex,
	borndate,
	phone,
	photo,
	boyfriend_id
)
VALUES
	(
		13,
		'唐艺昕',
		'女',
		'1990-4-23',
		'1898888888',
		NULL,
		2
	);

#方法二:
INSERT INTO beauty (id, NAME, sex, phone)
VALUES
	(
		15,
		'娜扎',
		'女',
		'1388888888'
	);

#3.列的顺序是否可以调换?可以
INSERT INTO beauty (NAME, sex, id, phone)
VALUES
	('蒋欣', '女', 16, '110');

#4.列数和值的个数必须一致
INSERT INTO beauty (NAME, sex, id, phone)
VALUES
	('关晓彤', '女', 17, '110');

#5.可以省略列名,默认所有列,而且列的顺序和表中列的顺序一致
INSERT INTO beauty
VALUES
	(
		18,
		'张飞',
		'男',
		NULL,
		'119',
		NULL,
		NULL
	);
#方式二:
/*
语法:
insert into 表名
set 列名=值,列名=值,...
*/

INSERT INTO beauty
SET id = 19,
 name = '刘涛',
 phone = '999';

二、修改

修改单表语法:

update 表名 set 字段=新值,字段=新值
【where 条件】

修改多表语法:

sql92标准语法:
update 表1 别名,表2 别名
set 列=值,...
where 连接条件
and 筛选条件;

sql99标准语法:
update 表1 别名
inner|left|right join 表2 别名
on 连接条件
set 列=值,...
where 筛选条件;

示例1:修改单表

#修改beauty表中姓唐的女神的电话为13899888899
UPDATE beauty
SET phone = '13899888899'
WHERE
	NAME LIKE '唐%';

#修改boys表中id号为2的名称为张飞,魅力值 10
UPDATE boys
SET boyname = '张飞',
 usercp = 10
WHERE
	id = 2;

示例2:修改多表

#修改张无忌的女朋友的手机号为114
UPDATE boys bo
INNER JOIN beauty b ON bo.`id` = b.`boyfriend_id`
SET b.`phone` = '114',
WHERE
	bo.`boyName` = '张无忌';

#修改没有男朋友的女神的男朋友编号都为2号
UPDATE boys bo
RIGHT JOIN beauty b ON bo.`id` = b.`boyfriend_id`
SET b.`boyfriend_id` = 2
WHERE
	bo.`id` IS NULL;

三、删除

方式1:delete语句

单表的删除: ★

delete from 表名 【where 筛选条件】

多表的删除:

sql92语法:
delete 表1的别名,表2的别名
from 表1 别名,表2 别名
where 连接条件
and 筛选条件;

sql99语法:
delete 表1的别名,表2的别名
from 表1 别名
inner|left|right join 表2 别名 on 连接条件
where 筛选条件;

示例1:

#单表的删除
#删除手机号以9结尾的女神信息
DELETE
FROM
	beauty
WHERE
	phone LIKE '%9';
#多表的删除
#删除张无忌的女朋友的信息
DELETE b
FROM
	beauty b
INNER JOIN boys bo ON b.`boyfriend_id` = bo.`id`
WHERE
	bo.`boyName` = '张无忌';

#删除黄晓明的信息以及他女朋友的信息
DELETE b,bo
FROM 
	beauty b
INNER JOIN boys bo ON b.`boyfriend_id`=bo.`id`
WHERE 
	bo.`boyName`='黄晓明';
方式2:truncate语句

用于清空一个表

语法:
truncate table 表名
两种方式的区别【面试题】

​ 1.truncate不能加where条件,而delete可以加where条件

​ 2.truncate的效率高一丢丢

3.truncate 删除带自增长的列的表后,如果再插入数据,数据从1开始
​ delete 删除带自增长列的表后,如果再插入数据,数据从上一次的断点处开始

​ 4.truncate删除不能回滚,delete删除可以回滚

DDL语句

数据定义语言

一、库和表的管理

库的管理:
一、创建库
create database 库名
二、删除库
drop database 库名
/*
语法:
create database  [if not exists]库名;
*/

#1、创建库Books
CREATE DATABASE
IF NOT EXISTS books;

#2、库的修改【该命令已经不能用】
RENAME DATABASE books TO booksx;

#3、更改库的字符集
ALTER DATABASE books CHARACTER
SET utf8;

#4、库的删除
DROP DATABASE
IF EXISTS books;

表的管理:
创建、修改、删除

创建: create
修改: alter
删除: drop
1、创建表
/*
创建表语法:
create table [IF 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)
);
2、修改表
①修改字段名
ALTER TABLE 表名 CHANGE  [COLUMN] 旧字段名 新字段名 CHAR(字段类型);
②修改表名
ALTER TABLE 旧表名 RENAME [TO]  新表名;
③修改字段类型和列级约束
ALTER TABLE 表名 MODIFY COLUMN 字段名 需要修改的类型名 ;
④添加字段
ALTER TABLE 表名 ADD COLUMN 字段名 VARCHAR(20) [first];
⑤删除字段
ALTER TABLE 表名 DROP COLUMN 字段名;
3、删除表
DROP TABLE [IF EXISTS] 表名;
4、表的复制
#1、仅仅复制表的结构
CREATE TABLE 新表名 LIKE 要复制的表名;

#2、复制表的结构+数据
CREATE TABLE 新表名 SELECT
	*
FROM
	要复制的表名;
	
#3、只复制部分数据
CREATE TABLE 新表名 SELECT
	要复制的字段
FROM
	要复制的表名
WHERE 条件;

#4、仅仅复制部分结构
CREATE TABLE 新表名 SELECT
	要复制的字段
FROM
	要复制的表名
WHERE 0(使条件恒不成立);

二、常见类型

数值型:
     整型: Tinyint、 Smallint、 Mediumint、 Int/Integer、 Bigint
     小数:
	     浮点型 :float 、 double
	     定点型(精度更高) :DEC(M,D)/DECTMAL(M,D) ,M指整数和小数的总位数,D是指小数位数,M和D都可以省略,M默						认为10,D默认为0
	     
字符型:
	较短的文本:char(M) 、 varchar(M),M代表最多几个字符。
			varchar是可变长度(查询效率低),不可省略;
			char是固定长度字符(查询效率高),M可省略,默认为1
	较长的文本:text 、 blob(用于保存较长的二进制数据,比如图片)

日期型:date、 datetime、 timestamp、 time、 year
date只保存日期,time只保存时间,year只保存年,datetime和timestamp保存日期+时间
datetime和timestamp的区别
	1、Timestamp支持的时间范围较小,取值范围:19700101080001——2038年的某个时间;Datetime的取值范围:1000-1-1 ——9999—12-31
	2、timestamp和实际时区有关,更能反映实际的日期,而datetime则只能反映出插入时的当地时区
	3、timestamp的属性受Mysql版本和SQLMode的影响很大

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

三、常见约束

约束是什么?

  • 为了保证数据的一致性和完整性,SQL规范以约 束的方式对表数据进行额外的条件限制。

  • 约束是表级的强制规定

  • 可以在创建表时规定约束(通过 CREATE TABLE 语句),或者在表创建之后也可以(通 过 ALTER TABLE 语句)

  • 有以下六种约束:

    • – NOT NULL 非空约束,规定某个字段不能为空

    • UNIQUE 唯一约束,规定某个字段在整个表中是唯一的 ,可以为空

    • PRIMARY KEY 主键(非空且唯一)

    • FOREIGN KEY 外键, 用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值
      在从表添加外键约束,用于引用主表中某列的值

    • CHECK 检查约束

    • DEFAULT 默认值

      注意: MySQL不支持check约束,但可以使用check约束,而没有任何效果;

添加约束的时机:

+ 1.创建表时
  • 2.修改表时

约束的添加分类:

  • 列级约束:六大约束语法上都支持,但外键约束没有效果
  • 表级约束:除了非空、默认,其他的都支持
主键和唯一的大对比:
		保证唯一性   是否允许为空    一个表中可以有多少个    是否允许组合
	主键	  √		     ×		       至多有1个            √,但不推荐
	唯一	  √		     √		       可以有多个           √,但不推荐

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

1、创建表时添加约束
#1.添加列级约束

/*
语法:
直接在字段名和类型后面追加 约束类型即可。
只支持:默认、非空、主键、唯一
*/
CREATE TABLE student (
	id INT PRIMARY KEY,
	#主键
	stuName VARCHAR (20) NOT NULL UNIQUE,
	#非空
	gender CHAR (1) CHECK (gender = '男' OR gender = '女'),
	#检查
	seat INT UNIQUE,
	#唯一
	age INT DEFAULT 18
	#默认约束
);


#2.添加表级约束

/*
语法:在各个字段的最下面
 【constraint 约束名】 约束类型(字段名) 
*/
CREATE TABLE major (
	id INT PRIMARY KEY,
	majorName VARCHAR (20)
);

CREATE TABLE student (
	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) #外键
);

#3、通用的写法:★
CREATE TABLE
IF NOT EXISTS student (
	id INT PRIMARY KEY,
	stuname VARCHAR (20),
	sex CHAR (1),
	age INT DEFAULT 18,
	seat INT UNIQUE,
	majorid INT,
	CONSTRAINT fk_stuinfo_major FOREIGN KEY (majorid) REFERENCES major (id)
);

2、修改表时添加约束
/*
语法:
1、添加列级约束
alter table 表名 modify column 字段名 字段类型 新约束;

2、添加表级约束
alter table 表名 add 【constraint 约束名】 约束类型(字段名) 【外键的引用】;
*/

#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 KEY(majorid) REFERENCES major(id); 
3、修改表时删除约束

#1.删除非空约束
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;

四、标识列

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

特点:

  • 1、标识列必须和主键搭配吗?不一定,但要求是一个key
  • 2、一个表可以有几个标识列?至多一个!
  • 3、标识列的类型只能是数值型
  • 4、标识列可以通过 SET auto_increment_increment=3;设置步长。可以通过手动插入值,设置起始值
  • 5、可以在修改表时添加标识列删除标识列
CREATE TABLE tab_identity (
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR (20)
);

INSERT INTO tab_identity
VALUES
	(NULL, 'john');
	
#或者下面写法
INSERT INTO tab_identity (NAME)
VALUES
	('lucy');
	
#设置步长	
SET auto_increment_increment=3;

#修改表时删除标识列
ALTER TABLE tab_identity MODIFY COLUMN id INT;

#修改表时添加标识列
ALTER TABLE tab_identity MODIFY COLUMN id INT PRIMARY KEY AUTO_INCREMENT;

数据库事务

TCL

Transaction Control Language 事务控制语言

事务的含义

   事务由单独单元的一个或多个SQL语句组成,在这个单元中,每个MySQL语句是相互依赖的。而整个单独单元作为一个不可分割的整体,如果单元中某条SQL语句一旦执行失败或产生错误,整个单元将会回滚。所有受到影响的数据将返回到事物开始以前的状态如果单元中的所有SQL语句均执行成功,则事物被顺利执行。

事务的ACID属性

1. 原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

2. 一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

3. 隔离性(Isolation)
事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

4. 持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响

事务的创建

  • 隐式事务:事务没有明显的开启和结束的标记。比如insert、update、delete等语句

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

相关步骤:

步骤1:开启事务
	set autocommit=0;
	start transaction;可选的
	
步骤2:编写事务中的sql语句(select insert update delete)
	语句1;
	语句2;
	...

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

事务的隔离级别

  • 事务并发问题如何发生?

    当多个事务同时操作同一个数据库的相同数据时

  • 事务的并发问题有哪些?

    脏读:一个事务读取到了另外一个事务未提交的数据
    不可重复读:同一个事务中,多次读取到的数据不一致
    幻读:一个事务读取数据时,另外一个事务进行更新,导致第一个事务读取到了没有更新的数据

  • 如何避免事务的并发问题?

    数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响, 避免各种并发问题.
    一个事务与其他事务隔离的程度称为隔离级别. 数据库规定了多种事务隔离级别, 不同隔离级别对应不同的干扰程度, 隔离级别越高, 数据一致性就越好, 但并发性越弱.

  • 事务隔离级别

1、READ UNCOMMITTED
2、READ COMMITTED 可以避免脏读
3、REPEATABLE READ 可以避免脏读、不可重复读和一部分幻读
4、SERIALIZABLE 可以避免脏读、不可重复读和幻读

Oracle 支持的 2 种事务隔离级别:READ COMMITED,SERIALIZABLE。 Oracle 默认的事务隔离级别为: READ COMMITED
Mysql 支持 4 种事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ

在这里插入图片描述

  • 设置隔离级别:

    session当前连接,global全局连接

set session|global  transaction isolation level 隔离级别名;
  • 查看隔离级别:
select @@tx_isolation;
  • savepoint 设置保存点
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点

视图

视图的含义

MySQL从5.0.1版本开始提供视图功能。一种虚拟存在的表,行和列的数据来自定义视图的查询中使用的表 ,并且是在使用视图时动态生成的,只保存了sql逻辑,不保存查询结果
  • 应用场景:

    • 多个地方用到同样的查询结果
    • 该查询结果使用的sql语句较复杂
  • 视图和表的区别:

           使用方式	     占用物理空间
    

    视图 完全相同 不占用,仅仅保存的是sql逻辑
    表 完全相同 占用

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

    1、sql语句提高重用性,效率高
    2、和表实现了分离,提高了安全性

视图的创建

# 语法:
CREATE VIEW  视图名
AS
查询语句;

修改视图

#方式一:
/*
create or replace view  视图名
as
查询语句;
*/
CREATE OR REPLACE VIEW myv3
AS
SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;

#方式二:
/*
语法:
alter view 视图名
as 
查询语句;
*/
ALTER VIEW myv3
AS
SELECT * FROM employees;

删除视图

/*
必须具有删除的权限
语法:drop view 视图名,视图名,...;
*/
DROP VIEW emp_v1,emp_v2,myv3;

查看视图结构

#方式一:
DESC 视图名;

#方式二:
SHOW CREATE VIEW 视图名;

视图数据的增删改查

视图数据的增删改查会更改原始表的数据,但有些视图不能更新,往往会对视图增加权限,一般只允许读取

#1、查看视图的数据 ★
SELECT * FROM my_v4;
SELECT * FROM my_v1 WHERE last_name='Partners';

#2、插入视图的数据
INSERT INTO my_v4(last_name,department_id) VALUES('Jhon',90);

#3、修改视图的数据
UPDATE my_v4 SET last_name ='Jhon' WHERE last_name='Tom';

#4、删除视图的数据
DELETE FROM my_v4 WHERE last_name='Tom';

某些视图不能更新

以下视图不能更新(增删改):

  • 包含以下关键字的sql语句:分组函数、distinct、group by、having、union或者union all
  • 常量视图
  • Select中包含子查询
  • join
  • 视图from一个不能更新的视图(视图中使用了另一个视图)
  • where子句的子查询引用了from子句中的表

存储过程

  • 含义:一组经过预先编译的sql语句的集合,理解成批处理语句

  • 好处:

    1、提高了sql语句的重用性,减少了开发程序员的压力
    2、简化操作,提高了效率
    3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率

  • 分类:

    1、无返回无参
    2、仅仅带in类型,无返回有参
    3、仅仅带out类型,有返回无参
    4、既带in又带out,有返回有参
    5、带inout,有返回有参
    注意:in、out、inout都可以在一个存储过程中带多个

创建存储过程

  • 语法:
create procedure 存储过程名(in|out|inout 参数名  参数类型,...)
begin
	存储过程体
end
  • 注意
1、参数列表包含三部分
参数模式  参数名  参数类型
举例: 
in stuname varchar(20)

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


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

语法:
delimiter 结束标记
案例:
delimiter $
CREATE PROCEDURE 存储过程名(IN|OUT|INOUT 参数名  参数类型,...)
BEGIN
	sql语句1;
	sql语句2;
	……
END $

调用存储过程

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

具体用法

  • 1.空参列表
#案例:插入到admin表中五条记录

DELIMITER $
CREATE PROCEDURE myp1()
BEGIN
	INSERT INTO admin(username,`password`) 
	VALUES('john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000');
END $

#调用
CALL myp1()$

#查看
SELECT * FROM admin$

  • 2.创建带in模式参数的存储过程
#案例1:创建存储过程实现 根据女神名,查询对应的男神信息

CREATE PROCEDURE myp2(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 $

#调用
CALL myp2('柳岩')$


#案例2 :创建存储过程实现,用户是否登录成功

CREATE PROCEDURE myp3(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
	DECLARE result INT DEFAULT 0;#声明并初始化
	SELECT COUNT(*) INTO result#赋值
	FROM admin
	WHERE admin.username = username
	AND admin.password = PASSWORD;
	SELECT IF(result>0,'成功','失败');#使用
END $

#调用
CALL myp3('张飞','8888')$

  • 3.创建out 模式参数的存储过程
#案例1:根据输入的女神名,返回对应的男神名

CREATE PROCEDURE myp6(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20))
BEGIN
	SELECT bo.boyname INTO boyname
	FROM boys bo
	RIGHT JOIN
	beauty b ON b.boyfriend_id = bo.id
	WHERE b.name=beautyName ;	
END $

#调用
CALL myp7('小昭',@name)$  #name变量用来接收返回值
#查看
SELECT @name$



#案例2:根据输入的女神名,返回对应的男神名和魅力值

CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT) 
BEGIN
	SELECT boys.boyname ,boys.usercp INTO boyname,usercp
	FROM boys 
	RIGHT JOIN
	beauty b ON b.boyfriend_id = boys.id
	WHERE b.name=beautyName ;	
END $

#调用
CALL myp7('小昭',@name,@cp)$
#查看
SELECT @name,@cp$

  • 4.创建带inout模式参数的存储过程
#案例1:传入a和b两个值,最终a和b都翻倍并返回

CREATE PROCEDURE myp8(INOUT a INT ,INOUT b INT)
BEGIN
	SET a=a*2;
	SET b=b*2;
END $

#赋值
SET @m=10$
SET @n=20$
#调用
CALL myp8(@m,@n)$
#查看
SELECT @m,@n$

删除存储过程

#语法:
drop procedure 存储过程名;

DROP PROCEDURE p1;
DROP PROCEDURE p2,p3;#不可行

查看存储过程的信息

DESC myp2;#不可行
SHOW CREATE PROCEDURE  myp2;

函数

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

  • 优点:

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

存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新
函数:有且仅有1 个返回,适合做处理数据后返回一个结果
		   关键字		 调用语法	    返回值			应用场景
函数        FUNCTION	 SELECT 函数()   只能是一个	一般用于查询结果为一个值并返回时,当有返回值而且仅仅一个
存储过程	PROCEDURE  CALL 存储过程()  可以有0个或多个  一般用于更新

创建函数

学过的函数:LENGTH、SUBSTR、CONCAT等

#语法:
CREATE FUNCTION 函数名(参数名 参数类型,...) RETURNS 返回类型
BEGIN
	函数体
END

注意:

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

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

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

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

调用函数

SELECT 函数名(实参列表)

具体使用

1.无参有返回
#案例:返回公司的员工个数
CREATE FUNCTION myf1() RETURNS INT
BEGIN
	DECLARE c INT DEFAULT 0; #定义局部变量
	SELECT COUNT(*) INTO c #赋值
	FROM employees;
	RETURN c;	
END $

SELECT myf1()$

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

SELECT myf2('k_ing')$


#案例2:根据部门名,返回该部门的平均工资
CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
BEGIN
	DECLARE sal DOUBLE ;
	SELECT AVG(salary) INTO sal
	FROM employees e
	JOIN departments d ON e.department_id = d.department_id
	WHERE d.department_name=deptName;
	RETURN sal;
END $

SELECT myf3('IT')$

#案例3:创建函数,实现传入两个float,返回二者之和
CREATE FUNCTION test_fun1(num1 FLOAT,num2 FLOAT) RETURNS FLOAT
BEGIN
	DECLARE SUM FLOAT DEFAULT 0;
	SET SUM=num1+num2;
	RETURN SUM;
END $

SELECT test_fun1(1,2)$

查看函数

SHOW CREATE FUNCTION myf3;

删除函数

DROP FUNCTION myf3;

流程控制结构

系统变量

  • 说明:变量由系统定义,不是用户定义,属于服务器层面
  • 注意:全局变量需要添加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;
SELECT @@session.tx_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 @变量名;
二、局部变量

作用域:仅仅在定义它的begin end块中有效,应用在 begin end中的第一句话

  • 声明 (可以不初始化):
declare 变量名 类型 【default 值】;
  • 赋值:
#方式一:一般用于赋简单的值
SET 变量名=值;
SET 变量名:=值;
SELECT 变量名:=值;

#方式二:一般用于赋表中的字段值
SELECT 字段名或表达式 INTO 变量
FROM 表;
  • 使用:
select 变量名
三、二者的区别
		    作用域			         定义位置		            语法
用户变量	 当前会话		         会话的任何地方		     加@符号,不用指定类型
局部变量	 定义它的BEGIN END中 	 BEGIN END的第一句话	       一般不用加@,需要指定类型

流程控制结构种类

顺序结构、分支结构、循环结构

分支结构

一、if函数
  • 语法:

    if(条件,值1,值2)
    
  • 特点:可以用在任何位置

二、case结构
  • 语法:

    情况一:类似于switch
    case 表达式
    when 值1 then 结果1或语句1(如果是语句,需要加分号)
    when 值2 then 结果2或语句2(如果是语句,需要加分号)

    else 结果n或语句n(如果是语句,需要加分号)
    end 【case】(如果是放在begin end中需要加上case,如果放在select后面不需要)

    情况二:类似于多重if
    case
    when 条件1 then 结果1或语句1(如果是语句,需要加分号)
    when 条件2 then 结果2或语句2(如果是语句,需要加分号)

    else 结果n或语句n(如果是语句,需要加分号)
    end 【case】(如果是放在begin end中需要加上case,如果放在select后面不需要)

  • 特点:
    可以用在任何位置

  • 用法

#案例1:创建函数,实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D

CREATE FUNCTION test_case(score FLOAT) RETURNS CHAR
BEGIN 
	DECLARE ch CHAR DEFAULT 'A';
	CASE 
	WHEN score>90 THEN SET ch='A';
	WHEN score>80 THEN SET ch='B';
	WHEN score>60 THEN SET ch='C';
	ELSE SET ch='D';
	END CASE;
	RETURN ch;
END $

SELECT test_case(56)$

作为表达式:

在这里插入图片描述
作为独立语句:
在这里插入图片描述

三、if 结构
  • 语法:

    if 情况1 then 语句1;
    elseif 情况2 then 语句2;

    else 语句n;
    end if;

  • 特点:
    只能用在begin end中!!!!!!!!!!!!!!!

  • 用法

#案例1:创建函数,实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D
CREATE FUNCTION test_if(score FLOAT) RETURNS CHAR
BEGIN
	DECLARE ch CHAR DEFAULT 'A';
	IF score>90 THEN SET ch='A';
	ELSEIF score>80 THEN SET ch='B';
	ELSEIF score>60 THEN SET ch='C';
	ELSE SET ch='D';
	END IF;
	RETURN ch;	
END $

SELECT test_if(87)$


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

CALL test_if_pro(2100)$
四、三者比较
		         应用场合                  应用位置
	if函数        简单双分支			  可以用在任何位置
	case结构	    等值判断的多分支        可以用在任何位置
	if结构	    区间判断的多分支        只能用在begin end中

循环结构

  • 分类:
    while、loop、repeat

  • 语法:

#while语法
【标签:】WHILE 循环条件  DO
	循环体
END WHILE 【标签】;

#loop语法,可以用来模拟简单的死循环
【标签:】loop
	循环体;
end loop 【标签】;

# repeat语法:
【标签:】repeat
	循环体;
until 结束循环的条件
end repeat 【标签】;
  • 特点:

    只能放在BEGIN END里面

    如果要搭配leave跳转语句,需要使用标签,否则可以不用标签

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

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

  • 用法

#1.没有添加循环控制语句
#案例:批量插入,根据次数插入到admin表中多条记录
DROP PROCEDURE pro_while1$
CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 1;
	WHILE i<=insertCount DO
		INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'666');
		SET i=i+1;
	END WHILE;	
END $

CALL pro_while1(100)$


#2.添加leave语句
#案例:批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 1;
	a:WHILE i<=insertCount DO
		INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
		IF i>=20 THEN LEAVE a;
		END IF;
		SET i=i+1;
	END WHILE a;
END $

CALL test_while1(100)$


#3.添加iterate语句
#案例:批量插入,根据次数插入到admin表中多条记录,只插入偶数次
TRUNCATE TABLE admin$
DROP PROCEDURE test_while1$
CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 0;
	a:WHILE i<=insertCount DO
		SET i=i+1;
		IF MOD(i,2)!=0 THEN ITERATE a;
		END IF;	
		INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');	
	END WHILE a;
END $

CALL test_while1(100)$

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值