MySQL基础 学习笔记–雷云龙
一、数据库相关概念:
DB:DataBase,存储数据的仓库,有组织,有规范
DBMS:Data Base Managemet System,数据库管理系统数据库是通过DBMS来创建和操作容器的
SQL: Structure Query Language: 结构化查询语言,专门用来与数据库通信的语言几乎所有的数据库都支持的语言
二 、数据库的特点
- 将数据放表中,表再放库中
- 一个数据库可以有多个表,每一个表都有一个名字,用来标识自己,表具有唯一性。
- 表的特性,定义了如何存储。类似类
- 每一个表由列组成,也就是字段,类似属性
- 表中的数据是按照行存储的,类似于对象
三、安装与使用
1、安装
百度
2、卸载
- 控制面板
- 删除安装位置的MySQL文件夹 C:\ProgramFilex86\MySQL 文件夹
- 删除隐藏文件:C:\ProgramData\MySQL
- 清理注册表:百度
3、配置文件
my.ini
4、配置环境变量(一般默认已经配好)
PATH中 MySQL的bean 配置尽量放在最前面
四、DQL查询语言
1、基础查询
1.1 略
1.2 去重 DISTINCT
SELECT DISTINCT `permission_id` FROM `t_role_permission`
1.3 + 加号的使用
-
如果是两个数值型,则做加法
-
如果是一个数值一个字符,则
如果成功 把字符转数值,做加法
如果失败 把字符当 0 ,做加法
-
一方为null 则结果是null
1.4 CONCAT拼接
SELECT CONCAT (`name`,`age`) AS information FROM `t_customer`
1.5 IFNULL
# 语句
SELECT
IFNULL(`seller_id`, 0) AS seller,
`seller_id`
FROM
`t_customer`
SELECT
CONCAT(
`age`,
`name`,
IFNULL(`seller_id`, 0)
) AS AAA
FROM
`t_customer`
2、条件查询
2.1 条件表达式
,> , <, =, !=, <>, >=, <=
2.2 按照逻辑表达式筛选
&& || !
2.3 模糊查询
like between…and in is ull
- like ,字符用单引号,% 表示通配符,_ 表示占位
SELECT * FROM `t_customer` WHERE `name` LIKE '%张%'
第二个字为飞的名字
SELECT
*
FROM
`t_customer`
WHERE `name` LIKE '_飞%'
斜杠转义下划线
第二个字符为下划线的名字
SELECT
*
FROM
`t_customer`
WHERE `name` LIKE '_\_%' ;
#------------------------------------
或者使用ESCAPE关键字,指定转义符
SELECT
*
FROM
`t_customer`
WHERE `name` LIKE '_M_%' ESCAPE 'M';
-
between…and 等价于 >= …<= …
包含临界值,并且只能从小到大
-
in
判断某字段是否属于in 列表的某一项
SELECT last_ name , job_ id FROM employees WHERE job_ id IN( 'IT_ _PROT' , 'AD_ _VP', 'AD_ PRES');
2.4 is null
因为 = <> 不能判断null 所以用 IS NULL IS NOT NULL
3、排序查询GROUP BY
3.1 升序 ASC
SELECT
`name`,
`age`
FROM
`t_customer`
GROUP BY `age` ASC
3.2 降序DESC
同理
4 、常见函数
1、单行函数
1.1 字符函数
-
concat 合并字段,
-
length(字段) 字节数,
-
ifnull(email,0)判空 ,
-
upper/lower 转大写/小写
-
substr/substring (‘字符’,Findex,Lindex)截取字符,sql 种的index都是从 1 开始的
-
trim 去前后空格, trim (‘a’ FROM ‘aaa张飞aaaaa’)去前后指定内容
-
lpad rpad 左填充,右填充
-
replace,替换
1.2 数学函数
- round:四舍五入 默认取整,roud(1.23,2):小数点后两位
- ceil: 向上取整 >= 它的最小整数。floor: 向下取整。
- truncate截断:truncate(1.234,2) -->1.23:截取小数点后两位
- mod取余:mod (10,3): 1 算法公式:a-a/b*b
1.3 日期函数
-
now():返回当前系统日期加时间
-
curdate():返回当前系统日期,不包含时间
-
curtime():返回当前时间,不包括日期
-
str_to_date():将日期格式的字符转换为日期
例: STR_TO_DATE(‘1-9-2020’, ‘%m-%d-%Y’) 2020-1-9 默认格式就是年月日
- date_format : 将日期转换成字符串
1.4 流程控制函数
-
if ():SELECT IF (10>5,‘大’,‘小’);
-
case():
案例: 查询员工的工资,要求
部门号=30,显示的工资为1.1倍
部门号=40,显示的工资为1.2倍
部门号=50,显示的工资为1.3倍
其他部门,显示的工资为原工资SELECT salary原始工资,department id, CASE department_ id WHEN 30 THEN salary*1.1 WHEN 40 THEN salary*1.2 WHEN 50 THEN salary*1.3 ELSE salary END AS新工资 FROM employees;
**案例:**查询员工的工资的情况
如果工资>20000,显示A级别
如果工资>15000,显示B级别
如果工资>10000, 显示c级别
否则,显示D级别
SELECT
salaryr
CASE
WHEN salary> 20000 THEN ,A'
WHEN salary> 15000
THEN'B'
WHEN salary> 10000 THEN↑ C'
ELSE ' D'
END AS工资级别
FROM employees ;
1.5 其他函数
- SELECT VERSION():查看版本号
- DATABASE():查看当前数据库
- USER():查看当前用户
2、分组函数
1.1 sum求和
sum(salary )
1.2 avg 平均值
1.3 min 最小值
1.4 max 最大值
1.5 count 总条数
1.6 搭配distinct去重
5、分组查询GROUP BY
1、简单的分组
# 查询每个部门的最大年龄
SELECT MAX(age),job_id FROM `t_customer` GROUP BY `job_id`
2、分组前的筛选
# 查询邮箱中包含‘z’ 字符的,每个部门的平均年龄
SELECT
AVG(`age`)
FROM
`t_customer`
WHERE `email` LIKE '%z%'
GROUP BY `job_id`
3、分组后的筛选
用having,分组后的条件过滤,没有分组用where ,有了分组用having
案例1:
#案例1:查询哪个部门的员工个数>2
#①查询每个部门的员工个数
SELECT COUNT (*) , department_id
FROM employees
GROUP BY department_id;
#②根据①的结果进行筛选,查询哪个部门的员工个数>2
SELECT COUNT (*) ,department_id
FROM employees
GROUP BY department_id
HAVING COUNT (*)>2;
案例2:
#案例2:查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
#①查询每个工种有奖金的员工的最高工资
SELECT MAX (salary) , job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id;
#②根据①结果继续筛选,最高工资>12000
SELECT MAX (salary) ,job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX (salary)> 12000;
案例3:
#案例3: 查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资
#①查询每个领导手下的员工固定最低工资
SELECT MIN (salary) ,manager_id
FROM employees
GROUP BY manager_id
#②添加筛选条件:编号>102
SELECT MIN (salary) ,manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id
#③添加筛选条件:最低工资>5000
SELECT MIN (salary) , manager_id
FROM employees
WHERE manager_id> 102
GROUP BY manager_id
HAVING MIN (salary) >5000;
特点:
分组查询中的筛选条件分为两类
数据源 位置 关键字
分组前筛选 原始表 group by子句的前面 where
分组后筛选 分组后的结果集 group by子句的后面 having
①分组函数做条件肯定是放在having子句中
②能用分组前筛选的,就优先考虑使用分组前筛选
4、按函数或表达式分组
#按表达式或函数分组
#案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些
#①查询每个长度的员工个数
SELECT COUNT(*) , LENGTH(last_name) len name
FROM employees
GROUP BY LENGTH(last_name) ;
#②添加筛选条件
SELECT COUNT(*) , LENGTH(last_name) len_name
FROM employees
GROUP BY LENGTH (last_name)
HAVING COUNT(*)> 5 ;
5、按多个字段进行分组
#按多个字段分组
#案例:查询每个部门每个工种的员工的平均工资
SELECT AVG (salary) , department_id, job_id
FROM employees
GROUP BY job_id, department_id;
6、添加排序
#添加排序
##案例:查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示
SELECT AVG (salary),department_id, job_id
FROM employees
GROUP BY job_id, department_id
ORDER BY AVG(salary) DESC;
7、注意
SELECT * FROM table where 条件 GROUP BY HAVING ORDERBY
排序的ORDER BY 放在最后
6、连接查询,多表查询
1、92语法(都是内连接)
1.1 等值连接
SELECT
name,
boyName
FROM
boys,
beauty
WHERE beauty.boyfriend_id = boys.id ;
案例1:
#案例1:查询有奖金的员工名、部门名
SELECT last_name , depa r tment_name , commission_pct
FROM employees e, depar tments d
WHERE e.department_id =d.department_id
AND e.commission pct
IS NOT NULL;
案例2:
#案例2:查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
SELECT depar tment_name,d.manager_id, MIN (salary)
FROM departments d, employees e
WHERE d.department_id =e.department_id
AND commission_ pct IS NOT NULL
GROUP BY depar tment_name , d.manager_id;
1.2 非等值连接
#案例1:查询员工的工资和工资级别
SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal;
1.3 自连接
2、99语法(推荐)
SELECT (查询列表)
FROM 表1 别名 (连接类型)
join 表2 别名
on 连接条件
【where 筛选条件】
【GROUP BY 分组】
【HAVING 筛选条件】
【ORDER BY 排序列表】
内连接:
2.1 等值连接
inner
语法:
SELECT (查询列表)
FROM 表1 别名
inner join 表2 别名
on 连接条件
-
案例1:
#案例1.查询员工名、部门名 SELECT last_name, depar tment_name FROM employees e INNER JOIN departments d ON e.department_id = d.department_id;
-
案例2:
#案例2.查询名字中包含e的员工名和工种名(添加筛选) SELECT last_ name, job_ title FROM employees e INNER JOIN jobs j ON e.job_id =j.job_id WHERE e.last name LIKE '%e%' ;
-
案例3:
#3.查询部门个数>3的城市名和部门个数, (添加分组+筛选) #①查询每个城市的部门个数 #②在①结果.上筛选满足条件的 SELECT city, COUNT(*)部门个数 FROM departments d INNER JOIN locations l ON d.location_id =l.location_id GROUP BY city HAVING COUNT(*)>3;
-
案例4:
#查询哪个部门的员工个数>3的部门名和员工个数,并按个数降序(添加排序) #并①查询每个部门的员工个数 SELECT COUNT (*) , depar tment_name FROM employees e INNER JOIN departments d ON e.department_id =d.department_id GROUP BY depar tment_name #②在①结果上筛选员工个数>3的记录,并排序 SELECT COUNT(*) 个数, depar tment_name EROM employees e INNER JOIN departmentsp d ON e.department_id =d.department_id GROUP BY depar tment_name HAVING COUNT (*)>3 ORDER BY COUNT (*) DESC;
-
案例5:
#5.查询员工名、部门名、工种名,并按部门名降序() SELECT last_name, department_name, job_title FROM employees e INNER JOIN departments d QN e.department_id =d.department_id INNER JOIN jobs j ON e.jbb_id = j.job_id ORDER BY department_name DESC;
2.2 非等值连接
-
案例1:
#查询员工的工资级别 SELECT salary,grade level FROM employees e JOIN job_grades g ON e.salary BETWEEN g.lowest_sal AND g.highest_sal;
-
案例2:
#查询工资级别的个数>20的个数,并且按工资级别降序 SELECT COUNT(*) ,grade level FROM employees e JOIN job_grades g ON e.salary BETWEEN g.lowest_sal AND g.highest_sal GROUP BY grade_level HAVING COUNT(*)>20 ORDER BY grade_level DESC;
2.3 自连接
#查询员工的名字、.上级的名字
SELECT e.last_name , m.last_name
FROM employees e
JQIN employees m
ON e.manager_id = m.employee_id;
外连接
特点:
1、外连接的查询结果为主表中的所有记录
如果从表中有和它匹配的,则显示匹配的值
如果从表中没有和它匹配的,则显示null
外连接查询结果=内连接结果+主表中有而从表没有的记录
2、左外连接,left join左边的是主表
右外连接,right join右边的是主表
3、左外和右外顺序互换,效果一样
2.4 左外连接:left outer
案例:哪个女生没有男朋友
#左外连接
SELECT b. name,bo.★
FROM beauty b
LEET OUTER JOIN boys bo
ON b.boyfriend_id = bo.id
WHERE bo.id IS NULL;
案例:哪个部门没有员工
#左外
SELECT d.*,e.employee_id
FROM departments d
LEFT OUTER JOIN employees e
ON d.department_id = e.department_id
WHERE e.employee_id IS NULL;
2.5 右外连接:rigte ourter
案例:哪个男生没有女朋友
SELECT b. name,bo. *
FROM boys bo
RIGHT OUTER JOIN beauty b
ON b.boyfriend_id = bo.id
WHERE bo.id IS NULL;
案例:哪个部门没有员工
#右外
SELECT d.*,e.employee_id
FROM employees e
RIGHT OUTER JOIN departments d
ON d.department_id = e.department_id
WHERE e.employee id IS NULL;
2.6 全外连接:full ourter(mysql 不支持,Oracle 支持)
交叉连接
也就是用99 语法实现的笛卡尔积
2.7 CROSS JOIN
#交叉连接
SELECT b.*,bo.★
FROM beauty b
CROSS JOIN
boys bo;
7、子查询
出现在其他查询语句中的SELECT 语句 ,可以单独执行
分类:
按子查询出现的位置:
select后面: 仅仅支持标量子查询
from后面: 支持表子查询
where或having后面: 标量子查询 列子查询 行子查询
exists后面(相关子查询):表子查询
按结果集的行列数不同:
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)
表子查询(结果集一- 般为多行多列)
1、where 或者 having 后面:
特点 :
- 子查询一般放在括号里
- 子查询一般放在条件右面
- 标量子查询一般搭配着单行操作符使用(> < = >= <= <>)
- 列子查询一般搭配着多行操作符使用(IN ,ANY,SOME,ALL,)
- 子查询的执行顺序优先于外查询
1.1 标量子查询(结果集只有一行一列)
案例1:
#案例1:谁的工资比Abel高?
#①查询Abe1的工资
SELECT salary
FROM employees
WHERE last_name = ' Abel '
#②查询员工的信息,满足salary>①结 果
SELECT *
FROM employees
WHERE salary> (
SELECT salary
FROM employees
WHERE last_name = ' Abel '
);
案例2:
#案例2:返回job_ id与141号 员工相同,salary比143号 员工多的员工姓名,job_ id和工资
#①查询141号员工的job_ id
SELECT job_id
FROM employees
WHERE employee_id = 141;
#②查询143号员工的salary
SELECT salary
FROM employees
WHERE employee_id = 143;
#③查询员工的姓名,job_ id和工资,要求job_ id=①并且salary>②
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
);
案例3:
#案例3:返回公司工资最少的员工的last_name, job_id和salary
#①查询公司的最低工资
SELECT MIN (salary)
FROM employees
#②查询last_name, job_id和salary, 要求salary=①
SELECT last_name, job_id, salary
FROM employees
WHERE salary= (
SELECT MIN (salary)
FROM employees
);
)]
案例4:
#案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资
#①查询50号部门的最低工资
SELECT MIN (salary)
FROM employees
WHERE department_id = 50
#②查询每个部门的最低工资
SELECT MIN (salary) , department_id
FROM employees
GROUP BY department_id
#③在②基础上筛选,满足min (salary)>①
SELECT MIN (salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN (salary)> (
SELECT
MIN (salary)
FROM employees
WHERE department_id = 50
);
1.2 列子查询(结果集只有一列多行)或多行子查询
案例1:
#列子查询(多行子查询)
#案例1:返回location_id是1400或1700的部门中的所有员工姓名
#①查询location_id是1400或1700的部门编号
SELECT DISTINCT depar tment_id
FROM depar tments
WHERE location_id IN(1400, 1700)
#②查询员工姓名,要求部门号是①列表中的某一个
SELECT last_name
FROM employees
WHERE department id IN(
SELECT DISTINCT depar tment_id
FROM depar tments
WHERE location_id IN(1400, 1700)
t) ;
案例2:
#案例2:返回其它工种中比job_id为'IT_PROG'工种任一工 资低的员工的员工号、姓名、job_id以及salary
#①查询job_id为'IT_PROG' 部门任一工资
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
#②查询员工号、姓名、job_id以及salary,salary< (①)的任意一个
SELECT last_name, employee_ id,job_ id, salary
FROM employees
WHERE salary<ANY (
SELECT DISTINCT salary
FROM employees
WHERE job_id = ' IT_PROG '
) AND job_ id<>' IT_ PROG' ;
1.3 行子查询(结果集有一行多列 ) 了解
案例1:
#案例:查询员工编号最小并且工资最高的员工信息.
#普通方法:
#①查询最小的员工编号
SELECT MIN (employee_id)
FROM employees
#②查询最高工资
SELECT MAX (salary)
FROM employees
#③查询员工信息
SELECT★
FROM employees
WHERE employee_id= (
SELECT MIN (employee_ id)
FROM employees
)AND salary= (
SELECT MAX (salary)
FROM employees
);
# 行子查询方法:
SELECT
FROM employees
WHERE (employee_id, salary)= (
SELECT MIN (employee_id) ,MAX (salary)
FROM employees
)
当两个都是 = 号的时候才会出现
2、select 后面:
案例1:
#案例:查询每个部门的员工个数
SELECT d.*,(
SELECT COUNT (*)
FROM employees e
WHERE e.department_id = d.department_id
)个数
FROM departments d;
3、 放在from后面
案例:
#案例:查询每个部门的平均工资的工资等级
#①查询每个部门的平均工资
SELECT AVG (salary) , department_id
FROM employees
GROUP BY depar tment_id
SELECT * FROM job_grades;
#②连接①的结果集和job_grades表,筛选条件平均工资between lowest_sal and highest_sal
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;
)]
4、放在exists后面(相关子查询)
# 语法:
# EXISTS(完整的查询字句)
# 返回结果只有0 和 1
SELECT EXISTS (SELECT username FROM `user`)
案例:
#案例:查询没有女朋友的男神信息
#in .
SELECT bo. *
FROM boys bo
WHERE bo.id NOT IN (
SELECT boyfriend_id
FROM beauty
)
#exists
SELECT bo. *
FROM boys bo
WHERE NOT EXISTS (
SELECT boyfriend_id
FROM beauty b
WHERE bo.id =b.boyfriend_id
) ;
8、分页查询 limit
limit ,放在所有查询之后,执行顺序也是最后
语法:
select查询列表
from表
[join type join表2
on连接条件
where筛选条件
group by分组字段
having分组后的筛选
order by排序的字段]
limit startindex,pagesize
startindex:起始索引,从0开始
pagesize:每页显示的个数
公式:如果需要第几页:
limit (pageNo -1)*pageSize,pageSize
案例1:
#案例:有奖金的员工信息,并且工资较高的前10名显示出来
SELECT
FROM
employees
WHERE commission_pct IS NOT NULL
ORDER BY salary DESC
LIMIT 10
9、union联合查询
引入案例:
#引入的案例:查询部门编号>90或邮箱包含a的员工信息
# 之前:
SELECT * FROM employees WHERE email LIKE '号a号' OR department_ id>90; ;
#使用联合查询:
SELECT *
FROM employees
WHERE email LIKE↑ 号a各'
UNION
SELECT * FROM employees
WHERE department id>90;
应用场景:
要查询的结果来自多个表,且多个表没有直接的连接关系,但查询的信息一致时。
#案例:查询中国用户中男性的信息以及外国用户中年男性的用户信息
SELECT id, cname,csex FROM t_ ca WHERE csex='男'
UNION
SELECT t_ id, tName, tGender FROM t_ ua WHERE tGender= 'male' ;
注意:
- 要求多条查询语句的查询列数是一致的
- 要求多条查询语句的查询的每一列的类型和数据最好是一致的
- union 关键字默认是去重的,可使用union all 保留重复项
五、DML 数据操作语言
1、插入语句
语法:
insert into 表名(列名,列名,列名…) values(值,‘字符值’…) 支持带着子查询插入
insert into set 列名 = 值,列名 = 值… 不支持子查询
注意:
- 插入的值与的类型要与列的类型一致或者兼容
- 可以为null的值,可以写列名值为null ,也可以不写列名。
- values 里面的值和 列名一一对应
2、修改语句
1、修改单表记录:
语法:
update 表名 set 列名 = 新值…where 筛选条件
2、修改多表记录
语法:
sq192语法:
update表1别名,表2别名
set
列=值....
where连接条件
and筛选条件;
sq199语法: .
update表1别名
innerlleftlright join表2别名
on
连接条件
set列=值...
where筛选条件;
案例:
#案例1:修改张无忌的女朋友的手机号为114.
UPDATE boys bo
INNER JOIN beauty b ON bo.id =b.boyfriend_id
SET b.phone'='114'
WHERE bo.boyName = 张无忌;
3、删除语句
1、单表删除
语法:
delete from 表名 where 筛选条件
#案例1:删除手机号以9结尾的女神信息
DELETE FROM beauty WHERE phone LIKE'%9';
2、多表关联删除
sq192语法:
delete表1的别名,表2的别名
from表1别名,表2别名
where连接条件
and筛选条件;
sq199语法:
delete表1的别名,表2的别名
from表1别名
inner lleftlright join 表2别名on连接条件
where筛选条件;|
案例:
#案例:删除张无忌的女朋友的信息
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 = 黄晓明;
六、DDL数据定义语言
创建:create 修改:alter 删除:drop
1、 库的管理
创建:
CREATE DATABASE [if not exists] 库名 [如果已经存在则不修改]
修改:
删除:
2、表的管理
创建:
create table 表名(
列名 列类型 长度 约束,
列名 列类型 长度 约束,
列名 列类型 长度 约束
)
修改:
删除:
3、常见数据类型
-
整型
-
浮点型
-
字符型
-
日期型
后续。。。
4、常见约束
1、NOT NULL: 非空
2、DEFAULT :保证该字段的默认值
3、PRIMARY KEY: 主见约束,保证唯一性,并且非空
4、UNIQUE: 保证唯一性,并且可以为空
5、CHECK :检查约束,mysql 不支持,但可以兼容
6、FOREIGN KEY : 外键约束
七、TCL 事务控制语言
Transation Control Language 事务控制语言
一组或多组sql 语句组成一个执行单元,要么全部执行,要么全部不执行
特性:
1 、原子性
2、一致性
3、隔离性
4、持久性
并发问题:
1、脏读:A 读了B 更新但没提交的数据
2、不可重复读:A读了一次,B 更新了,A又读了一次,两次数据不一样
3、幻读:A 读了一次,B 插入了,A再读就多了几行
隔离性级别:
Oracle :支持两种隔离级别,READ COMMITED(默认), SERIALIZABLE
Mysql :支持4中隔离级别,默认的是REPEATABLE READ
设置回滚点:
#演示savepoint的使用
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点
#结果是:28 没有被删除,25被删除
八、视图
使用场景:多次使用同一个查询语句,而这个语句又比较复杂的时候
#案例:查询姓张的学生名和专业名
SELECT stuname , maj orname
FROM stuinfo s
INNER JOIN major m ON s.majorid = m.id
WHERE s.stuname LIKE ' 张号' ;
CREATE VIEW v1
AS
SELECT stuname , maj orname
FROM stuinfo s
INNER JOIN major m ON s. majorid = m.id;
SELECT★FROM v1 WHERE stuname LIKE ' 张号' ;
九、变量
1、系统变量
注意:
如果是全局级别,则需要加GLOBAL,如果是会话级别,则需要加sESSION,如果不写,则默认SESSION
说明:
变量由系统提供的,不是用户定义,属于服务器层面
使用的语法:
1、查看所有的系统变量
show globallsession variables;
2、查看满足条件的部分系统变量
show global| [session]
variables like ‘号char号’ ;
3、查看指定的某个系统变量的值
select @@global1| [ session] .系统变量名;
4、为某个系统变量赋值
方式一:
set globall [session] 系统变量名 =值;
方式二:
set @@global| [session] . 系统变量名=值;
1、全局变量
作用域:服务器每次启动将为所有的全局变量赋初始值,针对于所有的会话(连接)有效,但不能跨重启
#①查看所有的全局变量
SHOW GLOBAL VARIABLES;
#②查看部分的全局变量
SHOW GLOBAL VARIABLES LIKE ’ 号char号’ ;
#③查看指定的全局变量的值
SELECT @ @global. autocommit ;
SELECT @@tx isolation;
#④为某个指定的全局变量赋值
SET @ @global . autocommit=0;
2、会话变量
作用域:只针对当前会话(连接)有效
#①查看所有的会话变量
SHOW VARIABLES;
SHOW SESSION VARIABLES;
并②查看部分的会话变量
SHOW VARIABLES LIKE ’ 号char号’ ;
SHOW SESSION VARIABLES LIKE ’ 号char号’ ;
#③查看指定的某个会话变量
SELECT @@tx_ isolation;
SELECT @@session. tx_ isolation;
#④为某个会话变量赋值
方式一:
SET @@tx_ isolation=’ read-uncommitted’ ;
方式二:
SET SESSION tx_ isolation =’ read- committed’ ;
2、自定义变量
后续。。。。
1、用户变量
2、局部变量
十、存储过程和函数
一组预先编译好的sql 的集合,理解成批处理语句
好处:
- 提高代码重用性
- 简化操作
- 减少了编译次数并且减少了数据库服务器的连接次数,提高效率
1、创建语法:
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的sQL语句)
END
注意:
1、参数列表包含三部分
参数模式 参数名 参数类型
举例:
IN stuname VARCHAR(20)
参数模式:
IN :用这个模式修饰的参数作为输入,也就是该参数需要调用方传入值
OUT: 输出参数,也就是返回值
**INOUT:**该参数既可以作为输入,又也可作为返回值
2、调用语法:
后续。。。
十一、流程控制结构
1、顺序结构
2、循环结构
3、分支结构
1、if 函数
语法:
IF (表达式1 ,表达式2,表达式3)
执行顺序:如果1 成立,则执行2,否则执行3
2、case
做等值判断,
语法:
CASE变量|表达式|字段
WHEN 要判断的值 THEN 返回的值1 或 返回的语句;
WHEN 要判断的值 THEN 返回的值1 或 返回的语句;
WHEN 要判断的值 THEN 返回的值1 或 返回的语句;
ELSE 要返回的值n 或语句 ;
END CASE;
做区间判断
语法:
CASE
WHEN 要判断的条件1 THEN 返回的值1或语句1;
WHEN 要判断的条件2 THEN 返回的值2或语句2;
ELSE 要返回的值n或语句n;
END CASE ;
特点:
①
可以作为表达式,嵌套在其他语句中使用,可以放在任何地方,BEGIN END中或BEGIN END的外面
可以作为独立的语句去使用,只能放在BEGIN END中
②
如果WHEN中的值满足或条件成立,则执行对应的THEN后面的语句,并且结束CASE
如果都不满足,则执行ELSE 中的语句或值
③ELSE可以省略,如果ELSE省略了,并且所有WHEN条件都不满足,则返回NULL
2、会话变量
作用域:只针对当前会话(连接)有效
#①查看所有的会话变量
SHOW VARIABLES;
SHOW SESSION VARIABLES;
并②查看部分的会话变量
SHOW VARIABLES LIKE ’ 号char号’ ;
SHOW SESSION VARIABLES LIKE ’ 号char号’ ;
#③查看指定的某个会话变量
SELECT @@tx_ isolation;
SELECT @@session. tx_ isolation;
#④为某个会话变量赋值
方式一:
SET @@tx_ isolation=’ read-uncommitted’ ;
方式二:
SET SESSION tx_ isolation =’ read- committed’ ;
2、自定义变量
后续。。。。
1、用户变量
2、局部变量
十、存储过程和函数
一组预先编译好的sql 的集合,理解成批处理语句
好处:
- 提高代码重用性
- 简化操作
- 减少了编译次数并且减少了数据库服务器的连接次数,提高效率
1、创建语法:
CREATE PROCEDURE 存储过程名(参数列表)
BEGIN
存储过程体(一组合法的sQL语句)
END
注意:
1、参数列表包含三部分
参数模式 参数名 参数类型
举例:
IN stuname VARCHAR(20)
参数模式:
IN :用这个模式修饰的参数作为输入,也就是该参数需要调用方传入值
OUT: 输出参数,也就是返回值
**INOUT:**该参数既可以作为输入,又也可作为返回值
2、调用语法:
后续。。。
十一、流程控制结构
1、顺序结构
2、循环结构
3、分支结构
1、if 函数
语法:
IF (表达式1 ,表达式2,表达式3)
执行顺序:如果1 成立,则执行2,否则执行3
2、case
做等值判断,
语法:
CASE变量|表达式|字段
WHEN 要判断的值 THEN 返回的值1 或 返回的语句;
WHEN 要判断的值 THEN 返回的值1 或 返回的语句;
WHEN 要判断的值 THEN 返回的值1 或 返回的语句;
ELSE 要返回的值n 或语句 ;
END CASE;
做区间判断
语法:
CASE
WHEN 要判断的条件1 THEN 返回的值1或语句1;
WHEN 要判断的条件2 THEN 返回的值2或语句2;
ELSE 要返回的值n或语句n;
END CASE ;
特点:
①
可以作为表达式,嵌套在其他语句中使用,可以放在任何地方,BEGIN END中或BEGIN END的外面
可以作为独立的语句去使用,只能放在BEGIN END中
②
如果WHEN中的值满足或条件成立,则执行对应的THEN后面的语句,并且结束CASE
如果都不满足,则执行ELSE 中的语句或值
③ELSE可以省略,如果ELSE省略了,并且所有WHEN条件都不满足,则返回NULL