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');
调用结果如下:

这个存储过程要点:
- 定义游标CURSOR;
- 为"not found"定义"CONTINUE HANDLER",作用是推出异常;
- 最后一个查询语句用户调用结果返回
2个列子介绍一些有用知识点,以后要是学到新的再逐步补充到这篇。