变量
系统变量
变量由系统提供,不是用户定义,属于服务器层面。
- 分类
- 全局变量:服务器每次启动将为所有的全局变量赋初始值,针对于所有的会话(连接) 有效;但不能跨重启
- 会话变量
- 查看变量(默认 SESSION)
- 查看所有的系统变量:
SHOW [GLOBAL|SESSION] VARIABLES
- 查看满足条件的部分系统变量:
SHOW [GLOBAL|SESSION] VARIABLES LIKE '%条件%'
- 查看指定的某个系统变量的值:
SELECT @@[GLOBAL|SESSION].系统变量名;
- 查看所有的系统变量:
- 为某个系统变量赋值(默认 SESSION)
SET [GLOBAL|SESSION] 系统变量名 = 值;
SET @@[GLOBAL|SESSION].系统变量名 = 值;
自定义变量
变量是用户自定义的,不是系统定义
使用步骤:声明 → 赋值 → 使用(查看、比较、运算等)
用户变量
- 作用域:针对于当前会话(连接) 有效,同于会话变量的作用域
- 声明并初始化
SET @用户变量名=值; SET @用户变量名:=值; SELECT @用户变量名:=值;
- 赋值(更新用户变量的值)
- 同声明初始化方式相同 ↑
- 使用 SELECT INTO
SELECT 字段 INTO 变量名 FROM 表; ------------------------- SELECT COUNT(*) INTO @empCount FROM employees;
- 案例:声明 2 个变量并赋初始值,求和并打印
SET @m=1; SET @n=2; SET @sum = @m + @n; SELECT @sum;
局部变量
- 作用域:仅仅在定义它的 BEGIN..END 中有效(还必须是其中的第 1 句话)
- 声明
DECLARE 变量名 类型; DECLARE 变量名 类型 DEFAULT 值;
- 赋值
SET 局部变量名=值; SET 局部变量名:=值; SELECT @局部变量名:=值;
- 使用
SELECT 局部变量名;
对比
- 用户变量
- 作用域:当前会话
- 定义和使用的位置:会话的任何地方
- 语法:必须加
@
符号,不用限定类型
- 局部变量
- 作用域:BEGIN...END 中
- 定义和使用的位置:只能在 BEGIN...END 中,声明必须在第 1 行
- 语法:一般不用加
@
符号,需要限定类型
流程控制
分支结构
IF 结构
- IF 函数:
IF(表达式1, 表达式2, 表达式3)
- IF 结构 // 只能应用在 BEGIN...END 中
IF 条件1 THEN 语句1; ELSEIF 条件2 THEN 语句2; ... [else 语句n;] END IF;
- 案例:创建函数实现根据传入的成绩返回对应的等级
CREATE FUNCTION getScoreLevel(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 $
CASE 结构
- 语法
- 类似于 Java 中的 switch 语句,一般用于实现等值判断
CASE 变量|表达式|字段 WHEN 判断的值 THEN 返回值1/语句1 WHEN 判断的值 THEN 返回值2/语句2 ... ELSE 返回值n/语句n END
- 类似于 Java 中的多重 if 语句,一般用于实现区间判断
CASE WHEN 判断条件1 THEN 返回值1/语句1 WHEN 判断条件2 THEN 返回值2/语句2 ... ELSE 返回值n/语句n END
- 类似于 Java 中的 switch 语句,一般用于实现等值判断
- 特点
- 作为表达式,嵌套在其它语句中使用,可以放在任何地方;若作为独立的语句去使用,只能放在 BEGIN...END 中
- 如果 WHEN 中的值满足或条件成立,则执行对应的 THEN 后面的语句,并且结束 CASE;如果都不满足,则执行 ELSE 中的语句或值
- ELSE 可以省略,如果 ELSE 省略且所有 WHEN 条件都不满足,则返回 NULL
- 案例:创建过程实现根据传入的成绩显示对应的等级
CREATE PROCEDURE getLevel(IN score INT) BEGIN CASE WHEN score >= 90 AND score <= 100 THEN SELECT 'A'; WHEN score >= 80 THEN SELECT 'B'; WHEN score >= 60 THEN SELECT 'C'; ELSE SELECT 'D'; END CASE; END $
循环结构
- 分类(仅能放在 BEGIN...END 中):while、loop、repeat
- 循环控制
- iterate 类似于 continue 继续,即结束本次循环,继续下一次
- leave 类似于 break 跳出,即结束当前所在的循环
语法
- while // 先判断后执行
[标签:] WHILE 循环条件 do 循环体; END WHILE [标签];
- loop // 可实现没有条件的死循环
[标签:] loop 循环体; END LOOP [标签];
- repeat // 先执行后判断
[标签:] repeat 循环体; UNTIL 结束循环的条件 END REPEAT [标签];
演示
- 批量插入,根据形参值插入到 admin 表指定多条记录
CREATE PROCEDURE whileTest1(IN count INT) BEGIN DECLARE i INT DEFAULT 1; WHILE i < count DO INSERT INTO admin VALUES(null, CONCAT('rose', i), '666'); SET i = i+1; END WHILE; END $
- [使用标签和 leave] 批量插入,根据形参值插入到 admin 表指定多条记录,如果次数大于 20 则停止
CREATE PROCEDURE whileTest2(IN count INT) BEGIN DECLARE i INT DEFAULT 1; labelW:WHILE i < count DO IF i > 20 THEN LEAVE labelW; END IF; INSERT INTO admin VALUES(null, CONCAT('jack', i), '888'); SET i = i+1; END WHILE labelW; END $
- [使用 iterate] 批量插入,根据形参值插入到 admin 表指定多条记录,只插入偶数次
CREATE PROCEDURE whileTest3(IN count INT) BEGIN DECLARE i INT DEFAULT 0; labelW:WHILE i < count DO SET i = i+1; IF MOD(i, 2) != 0 THEN ITERATE labelW; END IF; INSERT INTO admin VALUES(null, CONCAT('hana', i), '888'); END WHILE labelW; END $
- 向 stringcontent 表中插入指定个数的随机字符串
CREATE TABLE stringcontent ( id INT PRIMARY KEY AUTO_INCREMENT, content VARCHAR(30) )$ CREATE PROCEDURE randStrInsert(IN insertCount INT) BEGIN DECLARE i INT DEFAULT 1; # 定义一个循环变量i,表示插入次数 DECLARE str VARCHAR(26) DEFAULT 'abcdefghijklmnopqrstuvwxyz'; DECLARE startIndex INT DEFAULT 1; DECLARE len INT DEFAULT 1; WHILE i <= insertCount DO SET startIndex = FLOOR(RAND()*26+1); # 产生一个随机数[1~26] SET len = FLOOR(RAND()*(26-startIndex+1)+1); # 截取的字符串长度 INSERT INTO stringcontent VALUES(null, SUBSTR(str, startIndex, len)); SET i = i+1; END WHILE; END $