07.编程基础
逻辑控制与分支
if
if 函数:select *,if(age=1,"男","女") as ages from user; if 作为分支语句:
IF search_condition THEN
statement_list
[ELSEIF search_condition THEN]
statement_list ...
[ELSE
statement_list]
END IF
变量
概述
首先我们知道MySQL服务器维护了许多系统变量来控制其运行的行为,这些变量有些是默认编译到软件中的,有些是可以通过外部配置文件来配置覆盖的,如果想查询自编译的内置变量和从文件中可以读取覆盖的变量可以通过以下命令来查询: 注意下面命令都是在 linux 控制台中执行,不是在 DBMS 中执行
mysqld --verbose --help
# 只看自编译的内置变量
mysqld --no-defaults --verbose --help
接下来简单了解一下这几类变量的应用范围,首先MySQL服务器启动时会使用其软件内置的变量(俗称写死在代码中的)和配置文件中的变量(如果允许,是可以覆盖源代码中的默认值的)来初始化整个MySQL服务器的运行环境,这些变量通常就是我们所说的全局变量,这些在内存中的全局变量有些是可以修改的。
当有客户端连接到MySQL服务器的时候,MySQL服务器会将这些全局变量的大部分复制一份作为这个连接客户端的会话变量,这些会话变量与客户端连接绑定,连接的客户端可以修改其中允许修改的变量,但是当连接断开时这些会话变量全部消失,重新连接时会从全局变量中重新复制一份。
其实与连接相关的变量不只有会话变量一种,用户变量也是这样的,用户变量其实就是用户自定义变量,当客户端连接上MySQL服务器之后就可以自己定义一些变量,这些变量在整个连接过程中有效,当连接断开时,这些用户变量消失。
局部变量实际上最好理解,通常由DECLARE 关键字来定义,经常出现在存储过程中,非常类似于C和C++函数中的局部变量,而存储过程的参数也和这种变量非常相似,基本上可以作为同一种变量来对待。
变量的修改
先说全局变量有很多是可以动态调整的,也就是说可以在MySQL服务器运行期间通过 SET 命令修改全局变量,而不需要重新启动 MySQL 服务,但是这种方法在修改大部分变量的时候都需要超级权限,比如root账户。
相比之下会话对变量修改的要求要低的多,因为修改会话变量通常只会影响当前连接,但是有个别一些变量是例外的,修改它们也需要较高的权限,比如 binlog_format 和 sql_log_bin,因为设置这些变量的值将影响当前会话的二进制日志记录,也有可能对服务器复制和备份的完整性产生更广泛的影响。
至于用户变量和局部变量,听名字就知道,这些变量的生杀大权完全掌握在自己手中,想改就改,完全不需要理会什么权限,它的定义和使用全都由用户自己掌握。
全局变量
这些变量来源于软件自编译、配置文件中、以及启动参数中指定的变量,其中大部分是可以由root用户通过 SET 命令直接在运行时来修改的,一旦 MySQL 服务器重新启动,所有修改都被还原。如果修改了配置文件,想恢复最初的设置,只需要将配置文件还原,重新启动 MySQL 服务器,一切都可以恢复原来的样子。
# 查询所有全局不按量,大概有500多个,慎用
show global variables;
# 使用 like 查询部分
show global variables like 'sql%';
# 通过 select 查询
select @@global.sql_mode;
# 如果变量名称只存在于全局变量,不存在与会话变量时也可以这样:
select @@max_connections;
# 设置全局变量方法一
set global sql_mode='';
# 设置全局变量方法二
set @@global.sql_mode='';
会话变量
这些变量基本来自于全局变量的复制,与客户端连接有关,无论怎样修改,当连接断开后,一切都会还原,下次连接时又是一次新的开始。
# 查询所有会话变量
show session variables;
# 查询类似的会话变量
show session variables like 'sql%';
# 查询特定的会话变量
select @@session.sql_mode;
select @@local.sql_mode;
select @@sql_mode;
# 下面都是设置会话变量的方法
set session sql_mode = '';
set local sql_mode = '';
set @@session.sql_mode = '';
set @@local.sql_mode = '';
set @@sql_mode = '';
set sql_mode = '';
用户变量
用户变量就是用户自己定义的变量,也是在连接断开时失效,定义和使用相比会话变量来说简单许多 用户变量都不需要声明直接使用 - 这不就是 js 了吗
# 查询用户变量
select @count;
# 设置用户变量
set @count=1;
set @sum:=0;
select count(id) into @count from items where price < 99;
局部变量
declare 一般在begin...end 之间使用,在脱离存储过程的环境下一般使用 set 定义用户变量 局部变量通常出现在存储过程中,用于中间计算结果,交换数据等等,当存储过程执行完,变量的生命周期也就结束了
关于 declare 和 set 的使用注意:
mysql 不像sql server 需要事先使用 declare 声明变量,在要使用的时候直接 set @变量名称 = 1 即可 第一种用法:set @num=1; 或set @num:=1; //这里要使用变量来保存数据,直接使用@num变量 第二种用法:select @num:=1; 或 select @num:=字段名 from 表名 where …… 注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值” 第三种用法:select 字段名1,字段名2 into @变量1,@变量2 from 表名 where ...... 在函数或存储过程或触发器中,在不能使用set的时候推荐第三种,因为第二种会在执行时返回查询结果, 这在函数或触发器中会报 “Not allowed to return a result set from a function”错误。而第三种则不会报错。
# 声明局部变量,然后使用
declare count int(4);
select count;
# 设置局部变量
declare count int(4);
declare sum int(4);
set count=1;
set sum:=0;
# 也可以通过 select into 设置
declare count int(4);
select count(id) into count from items where price < 99;
in & exists
概述
查询范围内数据最简单的方法使用 in ,但是 mysql 中出现了查询结果超出指定范围的情况,后来使用 exists 解决了
案例
如下面的例子,使用 exists 查询在指定部门的员工的记录集,如果使用 in 会出现超出该范围的员工也被查询出来了
CREATE
DEFINER = root@localhost PROCEDURE usp_db_getDepartmentEmployeeBySid(IN departmentSid VARCHAR(100))
BEGIN
# 2021年1月7日 22:49:57
# 传入参数:department.sid
# 返回结果:从表 employee 查询得到数据集合
SELECT iid INTO @departmentId FROM department WHERE sid = departmentSid;
select * from employee AS e where exists (
SELECT d.sid
FROM department AS d WHERE find_in_set(d.iid,usf_getChildren_d(@departmentId))
AND d.sid = e.department_sid
);
END;
循环
概述
貌似 white 循环无法在代码片段中使用(网上搜索半天没找到成功案例),这里展示在存储过程中使用 white 的方法
CREATE
DEFINER = root@`%` PROCEDURE usp_whilePermission(IN inParentid INT)
BEGIN
SET @i:= 8;
WHILE @i<95 DO
INSERT INTO whitedatabase.sys_role_permission
(role_pk,permission_pk) values (1,@i);
set @i := @i+1;
END WHILE;
END;
