SQL语句 (MySQL)

登录操作

  • 参数 -u:user 用户
  • 参数 -p:password 密码
sql 复制代码
mysql -u Jack -p
  • 退出登录
sql 复制代码
exit;

控制与管理

展示用户列表

sql 复制代码
select user, host from mysql.user;

创建用户

  • UserName :填新用户的名称
  • HostName :允许该用户用什么主机登录数据库,填写 localhost127.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';
  • andor 用于在 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
*/

子查询

子查询是嵌套在 selectinsertupdatedelete 语句中的查询

  • 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;

创建触发器

  • 执行时间:beforeafter
  • 事件类型:insertupdatedelete
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 sqlno sqlreads sql datamodifies 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; 是一个处理器,当游标遍历完所有数据时会触发,设置doneTRUE
  • 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();
相关推荐
Ahern_34 分钟前
Oracle 普通表至分区表的分区交换
大数据·数据库·sql·oracle
夜半被帅醒1 小时前
MySQL 数据库优化详解【Java数据库调优】
java·数据库·mysql
不爱学习的啊Biao1 小时前
【13】MySQL如何选择合适的索引?
android·数据库·mysql
Rverdoser1 小时前
MySQL-MVCC(多版本并发控制)
数据库·mysql
醒了就刷牙1 小时前
黑马Java面试教程_P9_MySQL
java·mysql·面试
m0_748233642 小时前
SQL数组常用函数记录(Map篇)
java·数据库·sql
橘子师兄4 小时前
如何在自己的云服务器上部署mysql
运维·服务器·mysql
core5126 小时前
flink sink doris
大数据·mysql·flink·doris·存储·sink·过程正常
苹果酱05677 小时前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
Minxinbb7 小时前
MySQL中Performance Schema库的详解(上)
数据库·mysql·dba