前言

重新开始的MySQL

常见命令

  1. 查看表结构
  2. DESC 表名;
  3. 查看所有的库
  4. SHOW DATABASES;
  5. 打开指定库
  6. USE 库名;
  7. 查看当前库的所有表
  8. SHOW TABLES;
  9. 查看其它库的所有表
  10. SHOW TABLES FROM 库名;
  11. 创建表
  12. CREATE TABLES 表名(
  13. 列名,列类型;
  14. 列名,列类型
  15. );

语法规范

  1. 注释:
  2. 单行注释:#注释文字
  3. 单行注释:-- 注释文字
  4. 多行注释:/* 注释文字 */
  5. 转义:
  6. 在条件后面添加,用于查询字段中包含的特殊字符,这里使用ESCAPE$设置为转义符,也可以不使用ESCAPE,直接使用\
  7. SELECT
  8. last_name,
  9. salary
  10. FROM
  11. employees
  12. WHERE
  13. last_name LIKE '_$_%' ESCAPE '$';

常见函数

单行函数

字符函数

函数 作用
LENGTH(str) 获取参数的字节个数
CONCAT(str1, str2,…) 拼接字符
UPPER(str)、LOWER(str) 控制字符大小写
SUBSTR(str ,pos) 截取从pos开始到最后的字符(MySQL中的索引从1开始)
SUBSTR(str, pos, len) 截取包含pos开始len个长度的字符
INSTR(str,substr) 在str中查找substr,找不到返回0
TRIM(str) 去掉str中的空格
TRIM(chstr FROM str) 去掉str中前后的chstr
LPAD(str,len,padstr) 向str左填充padstr实现总长度len
RPAD(str,len,padstr) 向str右填充padstr实现总长度len
REPLACE(str,from_str,to_str) 将str中的from_str替换成to_str

数学函数

函数 作用
ROUND(X) 四舍五入
ROUND(X,D) 四舍五入保留D位小数
CEIL(X) 向上取整,返回>=该参数的最小整数
FLOOR(X) 向下取整,返回<=该参数的最大整数
TRUNCATE(X,D) 截断保留D位小数
MOD(N,M) 取余,可以套用N-N/M*M

日期函数

MySQL 基础 - 图1

函数 作用
NOW() 返回当前系统日期+时间
CURDATE() 返回当前系统日期(不包含时间)
CURTIME() 返回当前时间(不包含日期)
YEAR、MONTH、DAY(date) 年、月、日
HOUR、MINUTE、SECOND(date) 时 、分、秒
STR_TO_DATE(‘3-2 1998’,’%c-%d %Y’) 将字符通过指定的格式转换成日期
DATE_FORMAT(‘1998-03-02 00:00:00’,’%m月%d日 %Y年’) 将日期转换成字符
DATEDIFF(expr1,expr2) 两个日期之间的天数

其他函数

函数 作用

流程控制函数

  1. IF-ELSE
  2. `IF`(条件,结果1,结果2)
  3. CASE 1.
  4. CASE 字段或表达式
  5. WHEN 常量1 THEN 值或语句
  6. WHEN 常量2 THEN 值或语句
  7. ...
  8. ELSE 值或语句
  9. END
  10. CASE 2.
  11. CASE
  12. WHEN 条件1 THEN 值或语句
  13. WHEN 条件2 THEN 值或语句
  14. ...
  15. ELSE 值或语句
  16. END

分组函数

函数 作用
SUM([DISTINCT] expr)
AVG([DISTINCT] expr) 平均数
MIN([DISTINCT] expr) 最小值
MAX([DISTINCT] expr) 最大值
COUNT([DISTINCT] expr) 个数

可以与DISTINCT进行组合使用
COUNT(1)和COUNT(*)都可查询个数

DQL

基础查询

  1. 起别名(别名里有关键字时需要加双引号)
  2. 方式一:
  3. SELECT 列名 AS 别名, 列名 AS 别名 FROM 别名
  4. 方式二:
  5. SELECT 列名 别名, 列名 别名 FROM 别名
  6. 去重
  7. SELECT DISTINCT 列名 FROM 表名
  8. 合并列名查询
  9. SELECT CONCAT(字符1,字符2,...) AS 别名 FROM 表名

条件查询

  1. 条件表达式
  2. 简单条件运算符:>、< 、=、<>、 >=、 <=
  3. 逻辑表达式
  4. 逻辑运算符:&& || ! AND OR NOT
  5. 模糊查询
  6. LIKE:一般和通配符搭配使用
  7. %:任意多个字符包含0个字符
  8. _:任意单个字符
  9. LIKE('%字段%')
  10. (不在)在...之间
  11. (NOT) BETWEEN 条件 AND 条件
  12. IN
  13. 判断某字段的值是否属于IN列表中的某一项
  14. WHERE 列名 IN(value1,value2,...)
  15. IS NULLIS NOT NULL
  16. =或<>无法判断null
  17. <=>
  18. 完全等于:可以判断null

排序查询

  1. ASC 升序
  2. DESC 降序
  3. 默认是升序
  4. ORDER BY子句支持表达式、别名、函数、
  5. 多个字段排序
  6. ORDER BY 字段1 ASC, 字段2 DESC,...

分组查询

  1. SELECT 分组函数,列(需要出现在group by的后面)
  2. FROM
  3. WHERE 条件
  4. GROUP BY 分组列表
  5. HAVING 分组函数条件
  6. ORDER BY 列;
  7. PS:MySQL中的HavingOrder BY都支持别名查询,只有WHERE不支持。

连接查询

  1. SQL92
  2. SELECT 查询列表
  3. FROM 1 别名,表2 别名
  4. 等值:
  5. WHERE1.key=表2.key
  6. 非等值:
  7. WHERE非等值的连接条件
  8. 自连接:
  9. SELECT
  10. e.last_name,
  11. e.manager_id,
  12. ne.last_name
  13. FROM
  14. employees e,employees m
  15. WHERE
  16. e.manager_id = m.employee_id AND e.manager_id IS NOT NULL
  17. 也支持一部分外连接(用于oraclesqlservermysql不支
  18. 持)
  19. SQL99【推荐使用】
  20. SELECT 查询列表
  21. FROM 1 别名
  22. 内连接:
  23. INNER JOIN 2 别名 ON 连接条件
  24. 特点:
  25. 1.表的顺序可以调换
  26. 2.内连接的结果=多表的交集
  27. 3.n表连接至少需要n-1个连接条件
  28. 外连接:
  29. LEFT|RIGHT|FULLOUTER JOIN 2 别名 ON 连接条件
  30. 特点:
  31. 1.查询的结果=主表中所有的行,如果从表和它匹配将显示匹配行,如果从表不匹配则显示null
  32. 2.当需要查询主表哪一个数据未使用过时,确定好谁是主表,谁是从表,然后判断从表的唯一列是否为空即可
  33. 3.LEFT JOIN左边的就是主表,RIGHT JOIN右边的就是主表,FULL JOIN两边都是主表
  34. 4.一般用于查询除了交集部分的剩余的不匹配的行
  35. 交叉连接:
  36. CROSS JOIN 2 别名
  37. 特点:
  38. 查询结果类似于笛卡尔乘积

子查询

  1. 一、含义:
  2. - 嵌套在其他语句内部的SELECT语句称为子查询或内查询
  3. - 外面如果为SELECT语句,则此语句称为外查询或主查询
  4. 二、分类
  5. 1.按结果集的行列
  6. 标量子查询(单行子查询):结果集为一行一列
  7. 列子查询(多行子查询):结果集为多行一列
  8. 行子查询:结果集为多行多列
  9. 表子查询:结果集为多行多列
  10. 三、特点
  11. 单行子查询:
  12. - 子查询放在()内
  13. - 子查询一般放在条件的右侧
  14. - 标量子查询一般搭配单行操作符(>、<、>=、<=、=、<>)使用
  15. - 子查询的执行优先于主查询执行
  16. 多行子查询:
  17. - 结果集有多行
  18. - 一般搭配多行操作符使用:anyallinnot in
  19. - in 属于子查询结果中的任意一个就行
  20. - anyall往往可以用其他查询代替类似MINMAX
  21. 三、示例
  22. 1.WHEREHAVING后面
  23. IN()
  24. WHERE 字段 IN(单行子查询条件)
  25. WHERE 字段 = ANY(单行子查询条件)
  26. ANY()/SOME()
  27. WHERE 字段 < ANY(多行子查询条件)
  28. 判断字段小于或大于查询条件中的任意一个
  29. ALL()
  30. WHERE 字段 < ALL(多行子查询条件)
  31. 判断字段小于或大于所有查询条件
  32. 行子查询
  33. 例:
  34. SELECT *
  35. FROM employees
  36. WHERE (employee_id, salary) = (
  37. SELECT MIN(employee_id), MAX(salary)
  38. FROM employees
  39. );
  40. 2.SELECT后面
  41. 只支持标量子查询
  42. 例:
  43. SELECT d.department_name, (
  44. SELECT COUNT(*)
  45. FROM employees e
  46. WHERE d.department_id = e.department_id
  47. )
  48. FROM departments d;
  49. 3.FROM后面
  50. 将子查询结果充当一张表,必须起别名
  51. 例:
  52. 查询各部门的平均工资级别
  53. SELECT ag_dep.*, g.grade_level
  54. FROM (
  55. SELECT AVG(salary) ag, department_id
  56. FROM employees
  57. GROUP BY department_id
  58. ) ag_dep
  59. INNER JOIN job_grades g
  60. ON ag_dep.ag BETWEEN lowest_sal AND highest_sal ;
  61. 3.EXISTS后面(相关子查询)
  62. IN相通
  63. 结果:01
  64. 例:
  65. SELECT department_name
  66. FROM departments d
  67. WHERE EXISTS (
  68. SELECT *
  69. FROM employees e
  70. WHERE d.department_id = e.department_id
  71. );

分页查询

  1. 一、语法
  2. SELECT 查询列表
  3. FROM
  4. LIMIT [offset,] size
  5. PS:
  6. offset为起始条目,可省略(默认从0开始)
  7. size是要显示的条数
  8. 公式:
  9. 假设要显示的页数page,每页的条目数size
  10. limit (page-1)*size,size;

联合查询

  1. 一、语法
  2. 查询语句1
  3. UNION
  4. 查询语句2
  5. UNION
  6. ...
  7. ...
  8. 二、应用场景
  9. 要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致。
  10. 三、特点
  11. 1. 要求多条查询语句的查询列数一致
  12. 2. 要求多条查询语句的查询的每一列的类型和顺序最好一致
  13. 3. UNION关键字默认去重,非去重需要使用UNION ALL

总结

  1. 执行顺序
  2. SELECT 查询列表 7
  3. FROM 1
  4. 连接类型 JOIN 2 2
  5. ON 连接条件 3
  6. WHERE 筛选条件 4
  7. GROUP BY 分组列表 5
  8. HAVING 分组后的筛选 6
  9. ORDER BY 排序列表 8
  10. LIMIT 索引,条目数; 9

DML

插入

  1. 方式一:
  2. INSERT INTO 表名[(列名)]
  3. VALUES(值1,...),(值1,...);
  4. 方式二:
  5. INSERT INTO 表名
  6. SET 列名=值,列名=值,...;
  7. 方式三(方式一的子查询):
  8. INSERT INTO 表名[(列名)]
  9. SELECT (值1,...),(值1,...), UNION
  10. SELECT (值2,...),(值2,...), UNION
  11. SELECT (值3,...),(值3,...),

特点:

  1. 方式一和方式三需要保证列与值一一对应,但是列的顺序可以调换
  2. 方式一和方式三可以省略(列名),默认所有列
  3. 方式一和方式三列与值的个数必须一致,非空列也不除外
  4. 方式一支持一次插入多行,方式二不支持
  5. 方式一支持子查询,方式二不支持
  6. 方式一效果与方式三一样

修改

  1. 一、修改单表数据
  2. 语法:
  3. UPDATE 表名
  4. SET 列=新值,列=新值,...
  5. WHERE 条件;
  6. 二、修改多表数据
  7. SQL92语法:
  8. UPDATE 1 别名,表2 别名
  9. SET 列=新值,列=新值,...
  10. WHERE 条件
  11. AND 筛选条件;
  12. SQL99语法:
  13. UPDATE 1 别名
  14. INNER|LEFT|RIGHT| JOIN 2 别名
  15. ON 连接条件
  16. SET 列=值,...
  17. WHERE 筛选条件

删除

  1. 一、单表的删除
  2. 语法:
  3. DELETE FROM 表名 WHERE 筛选条件
  4. 二、多表的删除
  5. SQL92语法:
  6. DELETE 1的别名|表2的别名|表1的别名,表2的别名
  7. FROM 1 别名,表2 别名
  8. WHERE 连接条件
  9. AND 筛选条件;
  10. SQL99语法:
  11. DELETE 1的别名,表2的别名
  12. FROM 1 别名
  13. INNER|LEFT|RIGHT JOIN 2 别名 ON 连接条件
  14. WHERE 筛选条件;
  15. 三、删除整表
  16. 语法:
  17. TRUNCATE TABLE 表名;
  18. 四、对比
  19. 1. DELETE可以加WHERE,TRUNCATE不可以
  20. 2. TRUNCATE执行效率比DELETE高一些
  21. 3. TRUNCATE删除表之后,再添加数据时,自增列会从0开始,DELETE则是接着断点开始
  22. 4. TRUNCATE删除没有返回值,DELETE
  23. 5. TRUNCATE删除不能回滚,DELETE可以

DDL

库管理

  1. 1.创建【判断数据库是否存在,不存在则创建】
  2. CREATE DATABASE [IF NOT EXISTS] 库名 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
  3. 2.更改库的字符集
  4. ALTER DATABASE 库名 CHARACTER SET 字符格式
  5. 3.删除【判断数据库是否存在,存在则删除】
  6. DROP DATABASE [IF EXISTS] 库名
  7. 4.创建数据库并指定字符编码utf-8
  8. CREATE DATABASE `库名` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

表管理

  1. 1.创建
  2. CREATE TABLE IF NOT EXISTS 表名(
  3. 列名 列的类型 [约束],
  4. ...
  5. );
  6. 2.修改
  7. 修改列名
  8. ALTER TABLE 表名 CHANGE [COLUMN] 旧列名 新列名 新列名类型
  9. 修改列的类型和约束
  10. ALTER TABLE 表名 MODIFY [COLUMN] 列名 新类型 新约束
  11. 添加新列
  12. ALTER TABLE 表名 ADD [COLUMN] 列名 类型
  13. 删除列
  14. ALTER TABLE 表名 DROP COLUMN 列名
  15. 修改表名
  16. ALTER TABLE 表名 RENAME TO 新表名
  17. 3.删除
  18. DROP TABLE IF EXISTS 表名
  19. 4.复制
  20. 复制表结构
  21. CREATE TABLE 新表名 LIKE 被复制的表名
  22. 复制表结构加数据
  23. CREATE TABLE 新表名 SELECT * FROM 旧表
  24. 只复制部分数据
  25. CREATE TABLE 新表名 SELECT 需要复制的列名 FROM 旧表
  26. 仅复制某些字段
  27. CREATE TABLE 新表名 SELECT 需要复制的列名 FROM 旧表 WHERE 0

数据类型

整型

类型 字节
tinyint 1
smallint 2
mediumint 3
int/integer 4
bigint 8

特点:
①都可以设置无符号和有符号,默认有符号,通过unsigned设置无符号
②如果超出了范围,会报out or range异常,插入临界值
③长度可以不指定,默认会有一个长度
长度代表显示的最大宽度,如果不够则左边用0填充,但需要搭配zerofill,并且默认变为无符号整型

小数

浮点型:

类型 字节
float(M,D) 4
double(M,D) 8

定点型:

类型 字节
decimal(M,D) M+2

特点:
①M代表整数部位加小数部位,D代表小数部位,如果超出范围则插入临界值
②M和D都可以省略,如果是decimal,M默认为10,D默认为0,如果是float和double,则会根据插入的数值的精度来决定精度
③定点型精度较高, 如果要求插入数值精度较高,类似货币运算时,最好使用定点型
④所选择的类型越简单越好,能保存数值的类型越小越好

字符

较短的文本:

M的意思 特点 空间的耗费 效率
char(M) 最大的字符数,可以省略,默认为1 适合固定长度的字符 比较耗费
varchar(M) 最大的字符数,不可以省略 适合可变长度的字符 比较节省

binary和varbinary用于保存较短的二进制
enum保存枚举
set保存集合

日期

字节 范围 时区等影响
year 年 1
date 日期 4
time 时间 3
datetime 日期+时间 8 1000-9999 不受
timestamp 日期+时间 4 1970-2038

常见约束

用于限制表中的数据,为了保证表中数据的准确和可靠性。

列级约束

约束类型 作用
NOT NULL 非空,用于保证该字段的值不能为空
DEFAULT 默认,用于保证该字段有默认值
PRIMARY KEY 主键,用于保证该字段的值具有唯一性,并且非空
UNIQUE 唯一,用于保证该字段的值具有唯一性,可以为空
CHECK 检查约束【MySQL不支持】
FOREIGN KEY 外键,用于限制两个表的关系,用于保证该字段的值必须来自于朱标的关联列的值【不支持】

语法:
直接在字段名和类型后面追加约束类型即可

主键、唯一的对比:

保证唯一性 允许为空 一个表中可以有几个 允许组合
主键 一个 允许,PRIMARY KEY(列名,列名) ,不推荐
唯一 多个 允许,UNIQUE(列名,列名),不推荐

外键:

  1. 要求在从表设置外键关系
  2. 从表的外键列需要和主表的关联列类型一致或兼容,名称无要求
  3. 主表中的关联列必须是一个key(一般是主键或唯一)
  4. 插入数据时,需要先插入主表,再插入从表
  5. 删除数据时,需要先删除从表,再删除主表,也可以通过以下两种方式直接删除主表的记录
  1. 级联删除:
  2. 删除主表时,将删除所有引用主表的从表记录
  3. ALTER TABLE 表名
  4. ADD CONSTRAINT 自定义约束名
  5. FOREIGN KEY(外键列) REFERENCES 主键表(主键列)
  6. ON DELETE CASCADE
  7. 级联置空:
  8. 删除主表时,将对所有从表中的外键列设置为空
  9. ALTER TABLE 表名
  10. ADD CONSTRAINT 自定义约束名
  11. FOREIGN KEY(外键列) REFERENCES 主键表(主键列)
  12. ON DELETE SET NULL

表级约束

  1. 创建表级约束
  2. CREATE TABLE 表名(
  3. 列名 类型 长度,
  4. ...,
  5. CONSTRAINT 自定义约束名 约束类型(约束列),
  6. CONSTRAINT 自定义约束名 FOREIGN KEY(外键列) REFERENCES 主键表(主键列)
  7. );
  8. 查询表内约束信息
  9. SHOW INDEX FROM 表名

特点:

  1. 只支持主键、唯一、外键
  2. 一个列可以有多个约束

修改表时操作约束

  1. 添加列级约束
  2. ALTER TABLE 表名 MODIFY [COLUMN] 列名 类型 新约束
  3. 添加表级约束
  4. ALTER TABLE 表名 ADD [CONSTRAINT 约束名] 约束类型(字段名)
  5. 删除非空约束
  6. ALTER TABLE 表名 MODIFY [COLUMN] 列名 NULL
  7. 删除默认约束
  8. ALTER TABLE 表名 MODIFY [COLUMN] 列名 类型
  9. 删除主键约束
  10. ALTER TABLE 表名 DROP PRIMARY KEY
  11. 删除唯一约束
  12. ALTER TABLE 表名 DROP INDEX 约束名
  13. 删除外键约束
  14. ALTER TABLE 表名 DROP FOREIGN KEY 约束名
  15. 因为MySQL创建外键时还会创建一个对应的索引,所以删除外键后,还需要删除外键对应的索引,才能彻底删除
  16. 前缀 DROP INDEX 约束名

标识列

  1. 创建标识列
  2. CREATE TABLE 表名(
  3. 列名 类型 key约束 AUTO_INCREMENT
  4. )
  5. 修改表时设置标识列
  6. ALTER TABLE 表名 MODIFY [COLUMN] 列名 类型 新约束 AUTO_INCREMENT
  7. 删除标识列
  8. ALTER TABLE 表名 MODIFY [COLUMN] 列名 类型 约束
  9. 设置步长
  10. SET AUTO_INCREMENT_INCREMENT = 3

特点:

  1. 标识列需要与key搭配
  2. 一个表只能有一个标识列
  3. 标识列只能是数值型
  4. 可以通过手动插入值设置起始值

事务

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

一、ACID特性

  1. 原子性:一个事务的整体操作不可拆分,要么都成功,要么都失败
  2. 一致性:一个事务执行会使数据从一个一致状态切换到另一个一致状态
    以转账为例,转账之前 A 有 1000,B 有 1000, 如果 A 给 B 转 200,成功了,那么 A 就是 800,B 就是 1200,业务前后
    它们的总量都是 2000,不可能出现转完账之后,A 扣了 200,B 没加 200
  3. 隔离性:事务之间互相隔离
    假设有 100 个人都在下单,一个人下单失败了,他的数据回滚,不会影响其他人
  4. 持久性:一个事务一旦提交,则会永久的改变数据库的数据
    一旦事务保证了前3项特性,数据库通知事务提交成功了,那就一定会成功,就算数据库刚提示完成功,然后断电了,等再
    次启动数据库时,也能在数据库中发现数据的变化

二、创建

1、隐式事务

  • 没有明显的开启和结束的标记
  • 比如insert、update、delete语句

2、显式事务
具有明显的开启和结束的标记

  1. 步骤一:开启事务
  2. 必须先设置自动提交功能为禁用
  3. set autucommit = 0;
  4. [START TRANSACTION]
  5. 步骤二:
  6. 编写事务中的SQL语句
  7. 步骤三:结束事务
  8. COMMIT;提交事务
  9. ROLLBACK;回滚事务

3、隔离级别

效果
脏读 A事务未提交却被B事务读取到
不可重复读 A事务做了修改提交了, 同时开启的B事务读取到了修改后的结果
幻读 同时开启的两个事务中,A事务进行了查询,发现表内有两条数据,此时B事务向表中插入了一条数据并提交,A事务打算修改这两条数据,结果修改了三条数据
脏读 不可重复读 幻读
READ UNCOMMITED(读未提交数据)
READ COMMITED(读已提交数据) ×
REPEATABLE READ(可重复读) × ×
SERIALIZABLE(串行化,性能最差) × × ×
  1. MySQL默认REPEATABLE READ
  2. ORACLE默认READ COMMITED
  3. 查看当前隔离级别
  4. SELECT @@TX_ISOLATION
  5. 设置当前MySQL连接的隔离级别
  6. SET TRANSACTION ISOLATION LEVEL READ COMMITTED
  7. 设置数据库系统的全局的隔离级别
  8. SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED

4、回滚点

可以将事务回滚到SAVE POINT

  1. set autucommit = 0;
  2. [START TRANSACTION;]
  3. SQL语句1;
  4. SAVEPOINT 回滚点名称;
  5. SQL语句2;
  6. ROLLBACK 回滚点名称;

5、delete和truncate在事务使用时的区别
delete支持回滚,truncate不支持回滚

视图

一种虚拟存在的表,数据来自于查询时使用的表,当使用视图时会动态生成,只保存SQL逻辑,不保存查询结果

视图的好处

  1. 重用SQL语句
  2. 简化SQL,不必知道它的查询细节
  3. 与原始表相分离,提高了独立和安全性
  1. 一、创建
  2. CREATE VIEW 视图名
  3. AS
  4. 查询语句;
  5. 二、修改
  6. 方式
  7. CREATE OR REPLACE VIEW 视图名
  8. AS
  9. 查询语句;
  10. 方式2
  11. ALTER VIEW 视图名
  12. AS
  13. 查询语句;
  14. 三、删除
  15. DROP VIEW 视图名,视图名,...;
  16. 四、查看
  17. DESC 视图名;
  18. SHOW CREATE VIEW 视图名;

视图的使用

视图一般只用于查询,但是也支持像普通表一样的增删改,语法与普通表的一样

具备以下特点的视图不允许更新

  1. 包含以下关键字的SQL语句:分组函数、group by、distinct、having、union、union all
  2. 常量视图
  3. select中包含子查询
  4. join
  5. from一个不能更新的视图
  6. where子句的子查询引用了from子句中的表

变量

系统变量

由系统提供,不是用户自定义,属于服务器层面

一、全局变量
作用域:服务器每次启动将为所有的全局变量赋初始值,针对所有的会话(连接)有效,但不能跨重启

二、会话变量
作用域:仅针对当前会话(连接)有效

  1. 查询时,默认是会话级别SESSION,全局级别需要加GLOBAL
  2. 1.查看所有系统变量
  3. SHOW GLOBAL|[SESSION] VARIABLES
  4. 2.查看满足条件的部分系统变量
  5. SHOW GLOBAL|[SESSION] VARIABLES LIKE '%%'
  6. 3.查看指定的某个系统变量的值
  7. SELECT @@GLOBAL|[SESSION].系统变量名
  8. 4.为某个系统变量赋值
  9. 方式一:
  10. SET GLOBAL|[SESSION] 系统变量名 =
  11. 方式二:
  12. SET @@GLOBAL|[SESSION].系统变量名 =

自定义变量

一、用户变量
作用域:仅针对当前会话(连接)有效
定义和使用的位置:会话中的任何位置

  1. 声明并初始化
  2. 1) SET @用户变量名 =
  3. 2) SET @用户变量名:=
  4. 3) SELECT @用户变量名:=
  5. 赋值
  6. 1) 同声明并初始化
  7. 2) SELECT 字段 INTO 变量名 FROM
  8. 使用
  9. SELECT @用户变量名

二、局部变量
作用域:仅仅在定义它的begin end中有效
定义和使用的位置:只能用用在begin end中的第一句

  1. 声明
  2. DECLARE 变量名 类型
  3. 声明并初始化
  4. DECLARE 变量名 类型 DEFAULT
  5. 赋值
  6. 同自定义变量两种方式相同
  7. 使用
  8. SELECT 局部变量名

存储过程

一组预先编译好的SQL语句集合,可以理解成批处理语句,适合做批量插入、更新、删除

好处:

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

创建:

  1. CREATE PROCEDURE 存储过程名(参数列表)
  2. BEGIN
  3. 存储过程体
  4. END

注意:
一、参数列表包含三部分

  • 参数模式 参数名 参数类型
  1. 举例:
  2. IN STUNAME VARCHAR(20)
参数模式 效果
IN 输入参数,需要调用方传值
OUT 输出参数,会有返回值,一个存储过程中可以有多个
INOUT 既可输入也可输出的参数,需要传入值,并且有返回值
  • 如果存储过程体仅仅只有一句话,BEGIND END可以省略
  • 存储过程体中的每条SQL语句的结尾要求加分号
  • 存储过程的结尾可以使用DELIMITER重新设置

DELIMITER

DELIMITER声明在Navicat客户端中被屏蔽了,不需要加,但是在别的环境下需要加,例如命令行客户端中。

默认情况下,DELIMITER是分号,在命令行客户端中,如果有一行命令以分号结束,那么回车后,MySQL就会执行该命令,但是在存储过程的BEGIN END中,我们不希望MySQL这么做,这时就可以将DELIMITER更改为别的符号,例如:”DELIMITER $”,这样只有当 $符出现后,MySQL解释器才会执行。

调用

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

举例

  1. DELIMITER $
  2. #空参列表
  3. 1、向表中插入数据
  4. CREATE PROCEDURE myp1()
  5. BEGIN
  6. INSERT INTO admin VALUES(3,'qwe','123'),(4,'qwe','123'),(5,'qwe','123'),
  7. (6,'qwe','123'),(7,'qwe','123');
  8. END $
  9. CALL myp1()$
  10. #创建带IN模式参数的存储过程
  11. 1、创建存储过程实现用户是否登录成功
  12. DELIMITER $
  13. CREATE PROCEDURE myp3(IN username VARCHAR(20), IN PASSWORD VARCHAR(20))
  14. BEGIN
  15. DECLARE result INT MDEFAULT 0; #声明并初始化
  16. SELECT COUNT(*) INTO result #赋值
  17. FROM admin
  18. WHERE username = username
  19. AND admin.`password` = PASSWORD;
  20. SELECT IF(result>0,'登录成功','登录失败');#使用
  21. END $
  22. CALL myp3('john','8888')$
  23. #创建带OUT模式的存储过程
  24. #1、根据女神名,返回对应的男神名和男神魅力值
  25. CREATE PROCEDURE myp5(IN beautyName VARCHAR(20), OUT boyName VARCHAR(20),out userCP INT)
  26. BEGIN
  27. SELECT bo.boyName,bo.userCP INTO boyName,userCP
  28. FROM boys bo
  29. JOIN beauty b ON b.boyfriend_id = bo.id
  30. WHERE b.`name` = '小昭';
  31. END $
  32. CALL myp5('小昭',@bName,@userCP)$
  33. SELECT @bName,@buserCP$
  34. #创建INOUT参数的存储过程
  35. #1、传入a和b两个值,返回翻倍以后的a和b
  36. CREATE PROCEDURE myp6(INOUT a int, INOUT b INT)
  37. BEGIN
  38. SET a = a * 2;
  39. SET b = b * 2;
  40. END $
  41. SET @m = 10$
  42. SET @n = 20$
  43. CALL myp6(@m,@n)$
  44. SELECT @m,@n$

删除

  1. DROP PROCEDURE 存储过程名

查看存储过程的信息

  1. SHOW CREATE PROCEDURE 存储过程名

函数

含义同存储过程一样

创建

  1. CREATE FUNCTION 函数名(参数名 参数类型) RETURNS 返回类型
  2. BEGIN
  3. 函数体
  4. RETURN
  5. END

注意

  1. 函数体肯定会有return语句,如果没有会报错
  2. return语句可以放到任何位置,但建议放到最后
  3. 每个函数只有一个返回值
  4. 函数体只有一句时,可以省略begin end

调用

  1. SELECT 函数名(参数列表)

举例

  1. #根据部门名,返回该部门的平均工资
  2. CREATE FUNCTION myf3(dName VARCHAR(20)) RETURNS DOUBLE
  3. BEGIN
  4. DECLARE avgSal DOUBLE; #定义局部变量
  5. SELECT AVG(salary) INTO avgSal
  6. FROM departments d
  7. JOIN employees e ON d.department_id = e.department_id
  8. WHERE department_name = dName;
  9. RETURN avgSal;
  10. END $
  11. SELECT myf3('Adm')$

查看

  1. SHOW CREATE FUNCTION 函数名

删除

  1. DROP FUNCTION 函数名

流程控制结构

分支结构

一、IF函数
见流程控制函数↑
二、CASE结构
见流程控制函数↑
三、IF结构

  1. IF 条件1 THEN 语句1;
  2. ELSEIF 条件2 THEN 语句2;
  3. ...
  4. [ELSE 语句n;]
  5. END IF;
  • 只能应用于begin end中

循环结构

分类
while、loop、repeat

循环控制
itereate类似于continue,结束本次继续下一次
leave类似于break,结束当前所在的循环

语法

  1. WHILE:
  2. [标签:]WHILE 循环条件 DO
  3. 循环体
  4. END WHILE[标签]
  5. 标签:循环名
  6. LOOP:
  7. [标签:] LOOP
  8. 循环体
  9. END LOOP [标签]
  10. 可以用来模拟简单的死循环
  11. REPEAT:
  12. [标签:] REPEAT
  13. 循环体;
  14. UNTIL 结束循环的条件
  15. END REPEAT
  16. 至少执行一次,类似于JAVA中的dowhile

案例

  1. #根据参数批量插入偶数列数据
  2. CREATE PROCEDURE myp10(IN insertCount INT)
  3. BEGIN
  4. DECLARE i INT DEFAULT -1;
  5. a:WHILE i<=insertCount DO
  6. SET i = i+1;
  7. IF i % 2 != 0 THEN ITERATE a;
  8. END IF;
  9. INSERT INTO admin VALUES(i,CONCAT('admini',i),'123132');
  10. END WHILE a;
  11. END $
  12. #根据参数批量向表中添加随机字母
  13. CREATE TABLE stringcontent(
  14. id INT PRIMARY KEY auto_increment,
  15. content VARCHAR(20)
  16. );
  17. CREATE PROCEDURE test_randstr_insert(IN insertCount INT)
  18. BEGIN
  19. DECLARE i INT DEFAULT 1;#定义一个循环变量,表示插入次数
  20. DECLARE str VARCHAR(26) DEFAULT 'abcdefghijklmnopqrstuvwxyz';
  21. DECLARE startIndex INT DEFAULT 1;#代表起始索引
  22. DECLARE len INT DEFAULT 1;#代表截取的字符的长度
  23. WHILE i<=insertCount DO
  24. SET len = FLOOR(RAND()*(20-startIndex+1)+1);#产生一个随机整数,代表截取长度1- (20-startIndex+1)
  25. SET startIndex = FLOOR(RAND()*20+1);#产生一个随机的整数,代表起始索引1-26
  26. INSERT INTO stringContent(content) VALUES(SUBSTR(str,startIndex,len));
  27. SET i=i+1;#循环变量更新
  28. END WHILE;
  29. END $
  30. CALL test_randstr_insert(10)$
  31. SELECT * FROM stringContent