MySQL新学知识(二)MySQL存储过程

MySQL新学知识(二)


前言

👨‍💻👨‍🌾📝记录学习成果,以便温故而知新

本专题把一阶段学到知识MySQL做一个总结


一、mysql客户端建立存储过程

MySQL文档https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html中一个例子虽然简单,但是很有代表性。

例子如下:

mysql> delimiter //

mysql> CREATE PROCEDURE dorepeat(p1 INT)

-> BEGIN

-> SET @x = 0;

-> REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;

-> END

-> //

Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

mysql> CALL dorepeat(1000);

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x;

±-----+

| @x |

±-----+

| 1001 |

±-----+

1 row in set (0.00 sec)

客户端效果截图如下:

其中delimiter //是重新定义分隔符,默认分隔符是";"。因为存储过程体里语句的分隔符是";",而存储过程体的分隔符也是";",这样会有冲突,所以需要重新定义,这样存储过程体里语句使用";"作为分隔符就不会与存储过程体的分隔符"//"冲突了。

这个例子还演示了REPEAT循环与存储过程调用。

二、工具中建立存储过程

编辑已经建立的存储过程,与客户端的区别就是不要重新定义分隔符,省去了麻烦,如下图:

三、几个常用存储过程的例子

刚开始学Java的时候有种思路是所有的数据库操作都是用代码来实现以保证程序逻辑的可移植,防止换数据库还需要修改存储过程,所以对于存储过程的学习是浅尝辄止。后来发现有时存储过程还是很管用的,记录如下:

1.执行单语句

下面以新增用户权限为例

sql 复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `SP_ADD_PRIVILEGES`(IN `moduleName` varchar(100))
BEGIN
    -- 模块名称
    -- 如call SP_ADD_PRIVILEGES('模块名称');
    SET @grant_privileges = CONCAT('INSERT INTO t_privileges(user_id, module_name)
    SELECT user_id, \'', moduleName, '\' 
    FROM t_user
    WHERE role_name != \'Admin\' AND user_id NOT IN (SELECT user_id FROM t_privileges WHERE module_name = \'', moduleName, '\')');
    
    PREPARE stmt FROM @grant_privileges;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END

用户表内容如图:

调用存储过程如下:

sql 复制代码
CALL SP_ADD_PRIVILEGES('新增用户');

调用结果:

调用后t_privileges表内容:

这个存储过程的要点在于拼接语句。

2.循环执行语句

下面以给T开头的用户赋单表权限为例

sql 复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `SP_GRANTTABLE`(IN `tableName` varchar(100))
BEGIN
    -- 根据表名设置权限
    -- 如call SP_GRANTTABLE('test.t_privileges');
    DECLARE has_next boolean DEFAULT TRUE;
    DECLARE num int DEFAULT 0;
    DECLARE sqlStmt varchar(5000);
    DECLARE sqlResult CURSOR FOR SELECT CONCAT('GRANT Select ON TABLE ', tableName, ' TO `', User, '`@`%`;') FROM mysql.user WHERE User LIKE 'T%';
    DECLARE CONTINUE HANDLER FOR not found SET has_next = FALSE;
    
    OPEN sqlResult;
    EXIT_LOOP: LOOP
        FETCH sqlResult INTO sqlStmt;
        IF !has_next THEN
            LEAVE EXIT_LOOP;
        END IF;
        
        SET @grant_privileges = sqlStmt;
        PREPARE stmt FROM @grant_privileges;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET num = num + 1;
    END LOOP;
    CLOSE sqlResult;
    
    SELECT CONCAT('共授权', num, '位用户') AS '返回信息';
END

如下图红框新建两个用户:

调用存储过程如下:

sql 复制代码
CALL SP_GRANTTABLE('test.t_privileges');

调用结果如下:

这个存储过程要点:

  1. 定义游标CURSOR;
  2. 为"not found"定义"CONTINUE HANDLER",作用是推出异常;
  3. 最后一个查询语句用户调用结果返回

2个列子介绍一些有用知识点,以后要是学到新的再逐步补充到这篇。

相关推荐
luoluoal12 分钟前
基于深度学习的web端多格式纠错系统(源码+文档)
python·mysql·django·毕业设计·源码
eWidget12 分钟前
随机森林原理:集成学习思想 —— Java 实现多棵决策树投票机制
java·数据库·随机森林·集成学习·金仓数据库
Traced back20 分钟前
SQL Server 核心语法+进阶知识点大全(小白版)
数据库·sqlserver
资深web全栈开发24 分钟前
PostgreSQL枚举还是字符串:ENUM vs VARCHAR + CHECK 的权衡
数据库·postgresql
凯子坚持 c38 分钟前
C++基于微服务脚手架的视频点播系统---客户端(4)
数据库·c++·微服务
OceanBase数据库官方博客44 分钟前
OceanBase场景解码系列三|OB Cloud 如何稳定支撑中企出海实现数 10 倍的高速增长?
数据库·oceanbase·分布式数据库
m0_561359671 小时前
使用Python处理计算机图形学(PIL/Pillow)
jvm·数据库·python
山岚的运维笔记1 小时前
SQL Server笔记 -- 第14章:CASE语句
数据库·笔记·sql·microsoft·sqlserver
Data_Journal1 小时前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php
ASS-ASH1 小时前
AI时代之向量数据库概览
数据库·人工智能·python·llm·embedding·向量数据库·vlm