登录操作
- 参数
-u
:user 用户 - 参数
-p
:password 密码
sql
mysql -u Jack -p
- 退出登录
sql
exit;
控制与管理
展示用户列表
sql
select user, host from mysql.user;
创建用户
UserName
:填新用户的名称HostName
:允许该用户用什么主机登录数据库,填写localhost
或127.0.0.1
就只能本地登录,一般填写其他的 IP 地址,或者填写%
表示所有的主机UserPassword
:设置新用户的登录密码
sql
create user 'UserName'@'HostName' identified by 'UserPassword';
删除用户
sql
drop user 'UserName'@'HostName';
修改用户
- 修改用户密码
sql
alter user 'UserName'@'HostName' identified by 'NewPassword';
- 修改用户的名称和主机名
sql
rename user 'Old_UserName'@'Old_HostName' to 'New_UserName'@'New_HostName';
查看用户权限
sql
show grants for 'UserName'@'HostName';
授予权限
- 授予所有权限
sql
grant all privileges on *.* to 'UserName'@'HostName';
- 授予特定数据库的所有权限
sql
grant all privileges on `数据库的名称`.* to 'UserName'@'HostName';
- 授予特定数据库的某些权限
sql
grant select, insert, update, delete on `数据库的名称`.* to 'UserName'@'HostName';
- 授予特定表的某些权限
sql
grant select on `数据库的名称`.`表的名称` to 'UserName'@'HostName';
- 授予列级权限
sql
grant update(`列的名称`) on `数据库的名称`.`表的名称` to 'UserName'@'HostName';
- 授予创建和删除数据库的权限
sql
grant create, drop on *.* to 'UserName'@'HostName';
- 授予创建和删除用户的权限(通常只授予管理员)
sql
grant create user, drop user on *.* 'UserName'@'HostName';
- 授予远程登录权限(对于非本地主机)
sql
grant usage on *.* to 'UserName'@'HostName' identified by 'password';
收回权限
- 收回所有权限
sql
revoke all privileges on *.* from 'UserName'@'HostName';
- 收回特定数据库的所有权限
sql
revoke all privileges on `数据库的名称`.* from 'UserName'@'HostName';
- 收回特定表的权限
sql
revoke delete on `数据库的名称`.`表的名称` from 'UserName'@'HostName';
sql
revoke all privileges on `数据库的名称`.`表的名称` from 'UserName'@'HostName';
- 收回创建数据库的权限
sql
revoke create on *.* from 'UserName'@'HostName';
- 收回创建表的权限
sql
revoke create table on `数据库的名称`.* from 'UserName'@'HostName';
- 收回更新、插入、删除、查询数据的权限
sql
revoke update, insert, delete, select on `数据库的名称`.`表的名称` from 'UserName'@'HostName';
刷新权限
sql
flush privileges;
数据库操作
展示数据库
- 展示所有的数据库
sql
show databases;
创建数据库
sql
create database `数据库的名称`;
sql
create database if not exists `数据库的名称`;
sql
create database if not exists `数据库的名称` default charset `utf8` collate `utf8_general_ci`;
删除数据库
sql
drop database `数据库的名称`;
sql
drop database if exists `数据库的名称`;
使用数据库
sql
use `数据库的名称`;
更改数据库名称的流程
sql
-- 创建新数据库
create database `新数据库的名称`;
-- 将旧数据库的表复制到新数据库中
-- 假设我们有一个名为 abc 的表
create table `新数据库的名称`.`abc` like `旧数据库的名称`.`abc`;
insert into `新数据库的名称`.`abc` select * from `旧数据库的名称`.`abc`;
-- 删除旧数据库
drop database `旧数据库的名称`;
数据类型
数值类
数据类型 | 范围(有符号) | 范围(无符号) | 用途 |
---|---|---|---|
tinyint | -128 到 127 | 0 到 255 | 小整数值 |
smallint | -32768 到 32767 | 0 到 65535 | 较小的整数值 |
mediumint | -8388608 到 8388607 | 0 到 16777215 | 中等大小的整数值 |
int (integer) | -2147483648 到 2147483647 | 0 到 4294967295 | 标准整数值 |
bigint | -2^63 到 2^63-1 | 0 到 2^64-1 | 大整数值 |
float | -3.402823466E+38 到 -1.175494351E-38 | 0 到 3.402823466E+38 | 单精度浮点数值 |
double | -1.7976931348623157E+308 到 -2.2250738585072014E-308 | 0 到 1.7976931348623157E+308 | 双精度浮点数值 |
decimal (numeric) | 依赖于定义的位数 | 依赖于定义的位数 | 精确的小数值 |
时间日期类
数据类型 | 范围 | 格式 | 用途 |
---|---|---|---|
date | '1000-01-01' 到 '9999-12-31' | YYYY-MM-DD | 日期值 |
time | '-838:59:59' 到 '838:59:59' | HH:MM:SS | 时间值或持续时间 |
datetime | '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
timestamp | '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC | YYYY-MM-DD HH:MM:SS | 时间戳 |
year | 1901 到 2155 | YYYY | 年份值 |
字符串类
数据类型 | 最大长度 | 用途 |
---|---|---|
char | 255 字符 | 固定长度的字符串 |
varchar | 65535 字符 | 可变长度的字符串 |
tinytext | 255 字符 | 短文本字符串 |
text | 65,535 字符 | 长文本数据 |
mediumtext | 16,777,215 字符 | 中等长度的文本数据 |
longtext | 4,294,967,295 字符 | 极长文本数据 |
二进制数据类
数据类型 | 最大长度 | 用途 |
---|---|---|
binary | 255 字节 | 固定长度的二进制数据 |
varbinary | 65,535 字节 | 可变长度的二进制数据 |
tinyblob | 255 字节 | 小型二进制对象 |
blob | 65,535 字节 | 二进制大对象 |
mediumblob | 16,777,215 字节 | 中型二进制大对象 |
longblob | 4,294,967,295 字节 | 大型二进制大对象 |
其他特殊类型
数据类型 | 用途 |
---|---|
bit | 单个二进制位值 |
enum | 枚举,一个最多包含 65,535 个不同值的列表 |
set | 集合,一个最多包含 64 个不同值的集合 |
表操作
展示表
- 展示所有的表
sql
show tables;
- 查找以
user
开头的表
sql
show tables like 'user%';
- 检查表结构
sql
desc `数据库的名称`.`表的名称`;
创建表
sql
create table `表的名称` (
`id` int,
`name` varchar
);
sql
create table `表的名称` (
`id` int auto_increment primary key,
`name` varchar(3) null
);
sql
create table `数据库的名称`.`表的名称` (
`id` int auto_increment, -- 设置为自增
`sid` int,
`cid` int not null unique, -- 设置为非空且唯一
`name` varchar(20) null, -- 设置为空
`gender` char(1) default 'M', -- 设置默认为字符M
primary key (`id`, `sid`), -- 设置主键
constraint `给外键起名` foreign key (`cid`) references `数据库的名称`.`表的名称` (`字段的名称`)
);
删除表
sql
drop table `表的名称`;
sql
drop table if exists `表的名称`;
修改表
重命名表
sql
rename table `旧的表名` to `新的表名`;
更新表结构
- 添加列
sql
alter table `表的名称`
add `列的名称` `数据类型;`
- 删除列
sql
alter table `表的名称`
drop column `列的名称`;
- 修改列
sql
alter table `表的名称`
modify column `列的名称` `数据类型`;
- 修改列名
sql
alter table `表的名称`
change `旧的列名` `新的列名` `数据类型`;
- 添加主键
sql
alter table `表的名称`
add primary key (`列的名称`);
- 删除主键
sql
alter table `表的名称`
drop primary key;
- 添加索引
sql
create index `索引名称`
on `表的名称` (`列1`, `列2`, ...);
- 删除索引
sql
drop index `索引名称` on `表的名称`;
- 添加外键
sql
alter table `表的名称`
add constraint `设置外键名称`
foreign key (`列的名称`) references `某数据库`.`某表` (`列的名称`);
- 删除外键
sql
alter table `表的名称`
drop foreign key `外键的名称`;
- 更新表的字符集和排序规则
sql
alter table `表的名称`
convert to character set utf8mb4 collate utf8mb4_unicode_ci;
清空表数据
sql
truncate table `表的名称`;
复制表结构
sql
create table `新表的名称` like `旧表的名称`;
复制表数据和结构
sql
create table `新表的名称` as
select * from `旧表的名称`;
数据操作
插入数据
- 插入单行数据
sql
insert into `表的名称` (`列名1`, `列名2`, ...)
values ('值1', '值2', ...);
- 插入多行数据
sql
insert into `表的名称` (`列名1`, `列名2`, ...)
values ('值a1', '值a2', ...),
('值b1', '值b2', ...),
('值c1', '值c2', ...);
- 如果提供了所有列的值,则可以省略列名
sql
insert into `表的名称`
values ('值1', '值2', ...);
更新数据
sql
update `表的名称`
set `列的名称` = '值1',
`列的名称` = '值2',
...
where 条件;
删除数据
- 删除某一行
sql
delete from `表的名称`
where 条件;
- 删除所有数据(可以回滚)
sql
delete from `表的名称`;
- 清空表(删除速度更快,但不记录删除操作,无法回滚)
sql
truncate table `表的名称`;
数据查询
基本查询
- 普通查询,
select
后面跟着你想要查询的列名
sql
select `name`, `age`, `gender` from `UserTable`;
- 可以使用
*
来代表所有的列
sql
select * from `UserTable`;
distinct
关键字用于去除查询结果中的重复行
sql
select distinct `name` from `UserTable`;
条件查询
where
子句用于指定查询条件
sql
select * from `UserTable` where `name` = 'Tom';
and
和or
用于在where
子句中组合多个条件
sql
select * from `UserTable` where `name` = 'Tom' and `age` > 18;
- 一般的比较运算符,包括 =、>、<、>=、<=、!= 等
- 是否在集合中:in、not in
- 字符模糊匹配:like,not like
- 多重条件连接查询:and、or、not
排序查询
order by
子句用于对查询结果进行排序
sql
select * from `UserTable` order by `age`;
asc
为升序排序,desc
为降序排序
sql
select * from `UserTable` order by `age` desc;
聚合函数
- 聚合函数用于对一列数据进行计算,
count/sum/avg/min/max(...)
sql
select count(*) from `UserTable`;
distinct
表示去重再统计
sql
select sum(distinct `age`) from `UserTable`;
分组查询
group by
子句通常与聚合函数一起使用,用于对结果进行分组
sql
select `name` , count(`*`) from `UserTable` group up `gender`;
having
子句用于对分组后的结果进行进一步的条件过滤
sql
select `name`, count(`*`)
from `UserTable` group up `gender` having count(`*`) > 6;
分页查询
- 可以通过
limit
来限制查询的数量,只取前n个结果
sql
select * from `表的名称` limit 数量
sql
select * from `表的名称` limit 起始位置, 数量
连接查询
join...on
用于将行从两个或多个表基于某个相关列合并起来
sql
select UserTable.name ClassTable.name
from UserTable join ClassTable
on UserTable.id = ClassTable.id;
sql
/* SQL解释
从 UserTable 和 ClassTable 两个表中选取数据
只选择那些在 UserTable 和 ClassTable 中具有相同 id 值的行
对于每一行匹配的记录,它将返回 UserTable 中的 name 和 ClassTable 中的 id
*/
- 内连接:
inner join
- 左连接:
left join
- 右连接:
right join
- 全连接:
full join
sql
select UserTable.name ClassTable.name
from UserTable left join ClassTable
on UserTable.id = ClassTable.id;
sql
/* SQL解释
从 UserTable 表中选取所有行
对于 UserTable 中的每一行,尝试在 ClassTable 中找到具有相同 id 值的行
如果找到匹配的行,则返回 UserTable 的 name 和 ClassTabl e的 name
如果没有找到匹配的行,则仍然返回 UserTable 的 name,但 ClassTable 的 name 将为NULL
*/
子查询
子查询是嵌套在 select
、insert
、update
、delete
语句中的查询
- 在
UserTable
表中选择所有列的数据,但只选择那些其id
值与ClassTable
表中性别为男性的行相对应的记录
sql
select * from `UserTable`
where `id` in (
select `id` from `ClassTable`
where `gender` = 'M'
);
sql
/*
首先,子查询从 ClassTable 表中找出所有性别为男性的记录的 id
然后,外层查询使用这些 id 值来过滤 UserTable 表,只选择那些 id 存在于子查询结果集中的记录
最终,返回的是 UserTable 表中所有 id 与 ClassTable 表中性别为男性的记录相对应的完整记录
*/
视图
基本概念
视图的本质
-
视图的行为与表类似,但是它不存储数据,只存储定义
-
通过这个定义 ,它会查数据库并实时渲染成我们想要的查询结果
-
所以,你可以理解为视图本质就是一个查询的结果,而且这个结果是通过定义"现场制作"给我们看,按照我们想要的样子去查看数据
-
所以,这就是为什么视图它本身就是一个虚表,并不是真实存在的,数据实际上还是存放在原来的表中
视图的限制
- 视图可以简化复杂的SQL操作,但不会提升性能,因为视图在查询时是动态生成的
- 视图可能会不支持某些类型的更新操作,尤其是如果视图包含
聚合函数、distinct、group by、having、union
等 - 视图定义中不能包含
order by
子句,除非有limit
子句与之配合
视图的优点
- 安全性:限制用户只能访问他们需要的数据
- 简化复杂查询:可以将复杂的查询逻辑封装在视图中,使其他查询更简单
- 数据独立性:视图可以隐藏底层表结构的变化,使得应用程序不必修改
具体操作
创建视图
- 创建一个只有男性的姓名和年龄的视图
sql
create view `视图的名称` as
select `name`, `age` from `表的名称`
where `gender` = 'M';
查看视图
- 查看数据库中所有的视图
sql
show full tables in `数据库的名称`
where table_type like 'view';
- 查看特定视图的详细信息
sql
show create view `视图的名称`;
使用视图
- 使用视图与使用表类似,你可以对视图进行查询
sql
select * from `视图的名称`;
- 或者使用条件查询
sql
select * from `视图的名称` where 条件;
更新视图
- 更新视图通常是指修改视图的定义
sql
create or replace view `视图的名称` as
select `name`, `age` from `表的名称`
where `gender` = 'M';
删除视图
sql
drop view if exists `视图的名称`;
索引
基本概念
索引的用途
- 索引是用于提高查询性能 的数据结构,它们可以帮助快速定位表中的数据行
- 通过创建索引,提高我们的查询效率
索引的优缺点
优点
- 提高查询性能,尤其是在大数据集上
- 加速排序和分组操作
- 唯一索引可以确保数据的唯一性
缺点
- 索引会占用额外的磁盘空间
- 在插入、删除和更新操作时可能会降低性能,因为索引也需要维护
建议
- 我们应该根据实际的应用场景和数据模式,来决定是否创建索引,以及创建何种类型的索引
- 过多的索引可能会导致不必要的性能开销
具体操作
创建索引
- 索引包含
列1
,列2
...
sql
create index `索引的名称` on `UserTable` (`name`, `age`, `gender`);
查看索引
- 列出
UserTable
表上所有的索引以及相关信息,如索引类型、是否唯一、列等
sql
show index from `UserTable`;
删除索引
sql
drop index `索引的名称` on `UserTable`;
常见索引类型
主键索引
- 当你在创建表时定义主键时,MySQL 会自动为主键列创建一个主键索引
sql
create table `UserTable` (
`id` int auto_increment primary key,
...
);
唯一索引
sql
create unique index `索引的名称` on `UserTable` (`name`, `age`);
全文索引
sql
create fulltext index `索引的名称` on `UserTable` (`name`, `age`);
事务
基础认识
事务是数据库管理系统执行过程中的一个逻辑单位,由一系列操作组成,这些操作要么全部执行,要么全部不执行,保证了数据库的一致性和完整性
启动事务
sql
start transaction;
提交事务
- 确定事务中的所有操作,并将这些操作作为永久更改保存到数据库中
sql
commit;
回滚事务
- 用于撤销当前事务中所有的操作,即取消事务中的所有更改,并将数据库状态恢复到事务开始之前
sql
rollback;
具体示范
sql
-- 开启事务
start transaction;
-- 插入新用户的记录
insert into UserTable (name, age, gender, money) values ('Alice', 35, 'M', 0);
-- 获取新插入的用户的ID
-- @last_user_id 是自定义的变量,last_insert_id()是MySQL中的函数
set @last_user_id = last_insert_id();
-- 初始化用户的资金
update UserTable set money = 100 where user_id = @last_user_id;
-- 假设这里发生了一个错误,我们需要进行回滚操作
-- rollback;
-- 如果没有错误,则提交事务,保存更改
commit;
事务的隔离级别
read uncommitted
:允许读取尚未提交的数据变更,可能会导致脏读、不可重复读和幻读
sql
set transaction isolation level read uncommitted;
read committed
:只允许读取已经提交的数据变更,可以防止脏读,但不可重复读和幻读仍可能发生
sql
set transaction isolation level read committed;
repeatable read
:确保在事务内可以多次读取同样的数据结果,可以防止脏读和不可重复读,但幻读仍可能发生
sql
set transaction isolation level repeatable read;
serializable
:确保事务可以从数据库中检索到的数据,就好像其他事务不存在一样,是最严格的事务隔离级别,可以防止脏读、不可重复读和幻读
sql
set transaction isolation level serializable;
触发器
-
触发器就像其名字一样,在某种条件下会自动触发
-
触发器可以用于数据验证、日志记录以及复杂的业务逻辑等场景
查看触发器
sql
show triggers;
创建触发器
- 执行时间:
before
或after
- 事件类型:
insert
或update
或delete
sql
在数据库管理系统中,`DELIMITER` 是一个命令,用于改变MySQL中语句分隔符的符号。
默认情况下,MySQL命令行工具使用分号(`;`)作为语句结束的标志。
然而,在某些情况下,比如在创建存储过程或触发器时,需要在语句内部使用分号,而不希望它被解释为语句的结束。
这时,就可以使用 `DELIMITER` 命令来临时更改语句分隔符。
sql
-- 修改分隔符为 $ 符号
delimiter $
create trigger `触发器的名称`
执行时间 事件类型 on `表的名称`
for each row
begin
-- 这里写触发器要执行的SQL语句
if new.status != old.status then
insert into UserTable (name, age, gender)
values ('Jack', 35, 'M');
end if;
end;
-- 使用分隔符
$
-- 修改分隔符为原来的 ; 符号
delimiter ;
删除触发器
sql
drop trigger if exists `触发器的名称`;
函数
函数的分类
- 聚合函数 :对一组值进行计算,返回单个值。例如:
SUM()
,AVG()
,COUNT()
,MAX()
,MIN()
等 - 标量函数 :对单个值进行操作,返回一个单一的值。例如:
ABS()
,CEIL()
,FLOOR()
,ROUND()
等 - 日期和时间函数 :用于处理日期和时间值。例如:
NOW()
,CURDATE()
,CURTIME()
,DATE_ADD()
,DATEDIFF()
等 - 字符串函数 :用于处理字符串。例如:
CONCAT()
,LENGTH()
,LOWER()
,UPPER()
,SUBSTRING()
等 - 控制流函数 :如
CASE
表达式 - 加密函数 :例如
MD5()
,SHA1()
- 系统信息函数 :如
VERSION()
,USER()
函数的使用
聚合函数
sql
select count(*) from employees; -- 计算表中的行数
select sum(salary) from employees; -- 计算工资总和
select avg(salary) from employees; -- 计算平均工资
select max(salary) from employees; -- 找到最高工资
select min(salary) from employees; -- 找到最低工资
标量函数
sql
select abs (-1); -- 返回绝对值,结果为 1
select ceil(5.5); -- 向上取整,结果为 6
select floor(5.5); -- 向下取整,结果为 5
select round(5.567, 2); -- 四舍五入到小数点后两位,结果为 5.57
日期和时间函数
sql
select now(); -- 返回当前的日期和时间
select curdate(); -- 返回当前的日期
select curtime(); -- 返回当前的时间
-- 在当前日期上加一天
select date_add(now(), interval 1 day);
-- 计算两个日期之间的差值
select datediff('2024-10-4', now());
字符串函数
sql
-- 连接字符串,结果为 Hello World
select concat('Hello', ' ', 'World');
-- 返回字符串的长度,结果为 5
select length('MySQL');
-- 将字符串转换为小写,结果为 mysql
select lower('MySQL');
-- 将字符串转换为大写,结果为 MYSQL
select upper('MySQL');
-- 从第二个字符开始提取三个字符,结果为 ySQL
select substring('MySQL', 2, 3);
自定义函数
- 创建一个"返回两个数相加结果的"自定义函数
sql
-- 修改分隔符为 $ 符号
delimiter $;
create function AddTwoNumbers(a int, b int)
returns int
begin
declare sum int;
set sum = a + b;
return sum;
end;
-- 使用分隔符 $
$
-- 修改分隔符为原来的 ; 符号
delimiter ;
- 使用该函数
sql
select AddTwoNumbers(10, 20);
存储过程
基本认识
概念
- 如果在实现用户的某些需求时,需要编写一组复杂的 SQL 语句才能实现的时候,那么我们就可以将这组复杂的 SQL 语句集提前编写在数据库中,由 JDBC 调用来执行这组SQL语句。
- 把编写在数据库中的 SQL 语句集称为存储过程,调用存储过程可简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是很有好处的。
- 这就是数据库 SQL 语言层面的代码封装与重用。
优点
-
有助于减少应用程序和数据库服务器之间的流量。因为应运程序不必发送多个冗长的SQL语句,只用发送存储过程中的名称和参数即可
-
存储过程将数据库接口暴露给所有的应用程序,以方便开发人员不必开发存储过程中已支持的功能
-
存储的程序是安全的。数据库管理员可以 向访问数据库中存储过程的应用程序授予适当的权限,而不是向基础数据库表提供任何权限。
缺点
- 如果使用大量的存储过程,那么使用这些存储过程的每个连接的内存使用量将大大增加
- 如果在存储过程中过度使用大量的逻辑操作,那么 CPU 的使用率也在增加,因为 MySQL 数据库最初的设计就侧重于高效的查询,而不是逻辑运算
- 很难调试存储过程,而且 MySQL 不提供调试存储过程的功能
- 对数据库依赖程度较高,移值性差
组成部分
声明变量
sql
declare 变量名 类型;
sql
declare 变量名 类型 default 默认值;
变量赋值
sql
set 变量名 = 值;
条件语句
sql
if age < 18 then
-- SQL语句
elseif age < 35 then
-- SQL语句
else
-- SQL语句
end if;
循环语句
sql
while money > 100 do
-- SQL语句
set money = money - 10;
end while;
游标
- 游标就像是你在数据库里的一只手,它可以帮你一排一排地翻看查询出来的数据
- 并且可以针对每一排数据进行想要的操作,比如读取信息、修改内容或者删除记录
sql
declare `游标的名称` cursor for
-- 用于定义游标的select语句
open `游标的名称`;
fetch `游标的名称` into 用于存储从游标中提取的行数据的变量;
close `游标的名称`;
创建存储过程
in
表示输入参数
sql
create procedure `存储过程的名称` (in 参数 类型, ...)
begin
-- SQL语句
end;
调用存储过程
sql
call `存储过程的名称` (传值);
修改存储过程
characteristic
:可以指定存储过程的一些特性,如contains sql
、no sql
、reads sql data
、modifies sql data
等
sql
alter procedure `存储过程的名称` characteristic;
删除存储过程
sql
drop procedure if exists `存储过程的名称`;
使用演示
案例背景
-
假设我们有一个数据库表叫做
员工信息表
,里面记录了员工的姓名、部门和工资 -
现在我们需要给工资低于某个标准的员工涨工资
-
遍历所有员工,如果发现某个员工的工资低于5000元,那么就给他涨500元工资
存储过程
sql
-- 修改分隔符为 $ 符号
delimiter $
create procedure AdjustSalary()
begin
-- 声明变量
declare done int default false;
declare empName varchar(100);
declare empSalary decimal(10, 2);
-- 声明游标(它将遍历工资低于5000元的员工)
declare empCursor cursor for
select 姓名, 工资 from 员工信息表 where 工资 < 5000;
-- 声明循环结束的处理器(当游标遍历完所有数据时会触发:设置done为true)
declare continue handler for not found set done = true;
-- 打开游标
open empCursor;
-- 打开循环
read_loop: loop
-- 检查是否已经处理完所有数据
if done then
leave read_loop;
end if;
-- 从游标中获取数据
fetch empCursor into empName, empSalary;
-- 如果工资低于5000,则进行调整
if empSalary < 5000 then
-- 更新工资
update 员工信息表 set 工资 = empSalary + 500 where 姓名 = empName;
-- 可以在这里添加输出语句,比如打印调整后的工资
select concat('员工', empName, '的工资已调整为', empSalary + 500);
end if;
end loop;
-- 关闭游标
close empCursor;
end;
-- 使用分隔符 $ 符号
$
-- 修改分隔符为原来的 ; 符号
delimiter ;
代码分析
delimiter $
和delimiter ;
用于改变MySQL的语句结束符,因为我们想在存储过程中使用分号create procedure AdjustSalary()
开始定义一个名为AdjustSalary
的存储过程- 在存储过程中,我们声明了必要的变量和游标
declare empCursor cursor for ...
定义了一个游标,它将遍历工资低于5000元的员工declare continue handler for not found set done = true;
是一个处理器,当游标遍历完所有数据时会触发,设置done
为TRUE
open empCursor;
打开游标,准备开始遍历read_loop: loop ... end loop;
是一个循环,它会一直执行,直到所有的员工都被处理完毕fetch empCursor into empName, empSalary;
从游标中获取当前行的数据if done then ... end if;
是一个条件语句,用来检查是否已经到达游标的末尾if empSalary < 5000 then ... end if;
是另一个条件语句,用来判断是否需要调整工资update 员工信息表 set 工资 = empSalay + 500 where 姓名 = empName;
是一个更新语句,用来调整员工的工资close empCursor;
关闭游标
执行存储过程
sql
call AdjustSalary();