21 天 Python 计划:MySQL视图、触发器、存储过程、函数与流程控制
文章目录
- 一、视图
- 1.1 创建视图
- 1.2 使用视图
- 1.3 修改视图
- 1.4 删除视图
- 二、触发器
- 2.1 创建触发器
- 2.2 使用触发器
- 2.3 删除触发器
- 三、存储过程
- 3.1 介绍
- 3.2 创建简单存储过程(无参)
- 3.3 创建存储过程(有参)
- 3.4 执行存储过程
- 3.5 删除存储过程
- 四、函数
- 4.1 数学函数
- 4.2 聚合函数
- 4.3 字符串函数
- 4.4 日期和时间函数
- 4.5 加密函数
- 4.5.1 MD5()
- 4.5.2 PASSWORD(str)
- 4.6 控制流函数
- 4.6.1 CASE WHEN[test1] THEN [result1]...ELSE [default] END
- 4.6.2 CASE [test] WHEN[val1] THEN [result]...ELSE [default]END
- 4.6.3 IF(test,t,f)
- 4.6.4 IFNULL(arg1,arg2)
- 4.6.5 NULLIF(arg1,arg2)
- 4.7 控制流函数小练习
- 4.7.1 准备表
- 4.7.2 统计各科各分数段人数
- 五、自定义函数
- 5.1 创建自定义函数
- 5.2 删除函数
- 5.3 执行函数
- 六、流程控制
- 6.1 条件语句
- 5.2 循环语句
- 6.2.1 WHILE 循环
- 6.2.2 REPEAT 循环
- 6.2.3 LOOP 循环
- 结语
Python是一种强大且易于学习的编程语言。通过这个21天的计划,我们将逐步深入MySQL视图、触发器、存储过程、函数与流程控制。无论你是初学者还是有一定基础的开发者,这个计划都将帮助你巩固和扩展你的Python知识。
在学习本篇之前,我们先复习一下前面的内容:
day1:Python下载和开发工具介绍
day2:数据类型、字符编码、文件处理
day3:基础语法与课外练习
day4:函数简单介绍
day5:模块与包
day6:常用模块介绍
day7:面向对象
day8:面向对象高级
day9:异常处理
day10:网络编程
day11:并发编程
day12:MySQL数据库初识
day13:MySQL库相关操作
day14:MySQL表相关操作
day15:MySQL中DML与权限管理
一、视图
视图是一个虚拟表,它并不真实存在于数据库中,其本质是根据 SQL 语句获取动态的数据集,并为其命名。用户使用时只需使用这个名称即可获取结果集,就像操作普通表一样。
-- 两张有关系的表
mysql> select * from course;
+-----+--------+------------+
| cid | cname | teacher_id |
+-----+--------+------------+
| 1 | 生物 | 1 |
| 2 | 物理 | 2 |
| 3 | 体育 | 3 |
| 4 | 美术 | 2 |
+-----+--------+------------+
4 rows in set (0.00 sec)mysql> select * from teacher;
+-----+-----------------+
| tid | tname |
+-----+-----------------+
| 1 | 张磊老师 |
| 2 | 李平老师 |
| 3 | 刘海燕老师 |
| 4 | 朱云海老师 |
| 5 | 李杰老师 |
+-----+-----------------+
5 rows in set (0.00 sec)-- 查询李平老师教授的课程名
mysql> select cname from course where teacher_id = (select tid from teacher where tname='李平老师');
+--------+
| cname |
+--------+
| 物理 |
| 美术 |
+--------+
2 rows in set (0.00 sec)
1.1 创建视图
视图的创建语法为:CREATE VIEW 视图名称 AS SQL 语句。以下是一个示例:
-- 创建视图
create view teacher_view as select tid from teacher where tname='李平老师';-- 使用视图查询李平老师教授的课程名
mysql> select cname from course where teacher_id = (select tid from teacher_view);
+--------+
| cname |
+--------+
| 物理 |
| 美术 |
+--------+
2 rows in set (0.00 sec)
使用视图可以避免每次都重写复杂的子查询 SQL,但需要注意的是,视图的效率可能不如直接写子查询,而且视图存放在数据库中,如果程序中的 SQL 过分依赖视图,会导致扩展 SQL 极为不便。
1.2 使用视图
视图的数据修改会影响原始表,反之亦然。以下是一个示例:
mysql> select * from course;
+-----+--------+------------+
| cid | cname | teacher_id |
+-----+--------+------------+
| 1 | 生物 | 1 |
| 2 | 物理 | 2 |
| 3 | 体育 | 3 |
| 4 | 美术 | 2 |
+-----+--------+------------+
4 rows in set (0.00 sec)mysql> create view course_view as select * from course;
Query OK, 0 rows affected (0.52 sec)mysql> select * from course_view;
+-----+--------+------------+
| cid | cname | teacher_id |
+-----+--------+------------+
| 1 | 生物 | 1 |
| 2 | 物理 | 2 |
| 3 | 体育 | 3 |
| 4 | 美术 | 2 |
+-----+--------+------------+
4 rows in set (0.00 sec)mysql> update course_view set cname='xxx';
Query OK, 4 rows affected (0.04 sec)
Rows matched: 4 Changed: 4 Warnings: 0mysql> insert into course_view values(5,'yyy',2);
Query OK, 1 row affected (0.03 sec)mysql> select * from course;
+-----+-------+------------+
| cid | cname | teacher_id |
+-----+-------+------------+
| 1 | xxx | 1 |
| 2 | xxx | 2 |
| 3 | xxx | 3 |
| 4 | xxx | 2 |
| 5 | yyy | 2 |
+-----+-------+------------+
5 rows in set (0.00 sec)
不过,我们不建议修改视图中的记录,特别是在涉及多个表的情况下,修改视图记录可能会出现问题。
1.3 修改视图
修改视图的语法为:ALTER VIEW 视图名称 AS SQL 语句。示例如下:
mysql> alter view teacher_view as select * from course where cid>3;
Query OK, 0 rows affected (0.04 sec)mysql> select * from teacher_view;
+-----+-------+------------+
| cid | cname | teacher_id |
+-----+-------+------------+
| 4 | xxx | 2 |
| 5 | yyy | 2 |
+-----+-------+------------+
2 rows in set (0.00 sec)
1.4 删除视图
删除视图的语法为:DROP VIEW 视图名称。例如:
DROP VIEW teacher_view
二、触发器
触发器可以定制用户对表进行增、删、改操作时前后的行为,但不支持查询操作。
2.1 创建触发器
触发器的创建语法如下:
-- 插入前
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN...
END-- 插入后
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN...
END-- 删除前
CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN...
END-- 删除后
CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
BEGIN...
END-- 更新前
CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
BEGIN...
END-- 更新后
CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
BEGIN...
END
以下是一个具体的示例:
-- 准备表
CREATE TABLE cmd (id INT PRIMARY KEY auto_increment,USER CHAR (32),priv CHAR (10),cmd CHAR (64),sub_time datetime, -- 提交时间success enum ('yes', 'no') -- 0代表执行失败
);CREATE TABLE errlog (id INT PRIMARY KEY auto_increment,err_cmd CHAR (64),err_time datetime
);-- 创建触发器
delimiter //
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
BEGINIF NEW.success = 'no' THEN -- 等值判断只有一个等号INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; -- 必须加分号END IF ; -- 必须加分号
END//
delimiter ;-- 往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
INSERT INTO cmd (USER,priv,cmd,sub_time,success
)
VALUES('xiao','0755','ls -l /etc',NOW(),'yes'),('xiao','0755','cat /etc/passwd',NOW(),'no'),('xiao','0755','useradd xxx',NOW(),'no'),('xiao','0755','ps aux',NOW(),'yes');-- 查询错误日志,发现有两条
mysql> select * from errlog;
+----+-----------------+---------------------+
| id | err_cmd | err_time |
+----+-----------------+---------------------+
| 1 | cat /etc/passwd | 2017-09-14 22:18:48 |
| 2 | useradd xxx | 2017-09-14 22:18:48 |
+----+-----------------+---------------------+
2 rows in set (0.00 sec)
特别的,NEW表示即将插入的数据行,OLD表示即将删除的数据行。
2.2 使用触发器
触发器无法由用户直接调用,而是在对表进行增、删、改操作时被动触发。
2.3 删除触发器
删除触发器的语法为:drop trigger 触发器名称。例如:
drop trigger tri_after_insert_cmd;
三、存储过程
存储过程包含了一系列可执行的 SQL 语句,存放在 MySQL 中,通过调用它的名字可以执行其内部的 SQL 语句。
3.1 介绍
使用存储过程的优点是可以替代程序写的 SQL 语句,实现程序与 SQL 解耦,并且基于网络传输时,传别名的数据量小。缺点是程序员扩展功能不方便。
程序与数据库结合使用的三种方式:
-- 方式一:MySQL:存储过程程序:调用存储过程-- 方式二:MySQL:程序:纯 SQL 语句-- 方式三:MySQL:程序:类和对象,即 ORM(本质还是纯 SQL 语句)
3.2 创建简单存储过程(无参)
delimiter //
create procedure p1()
BEGINselect * from blog;INSERT into blog(name,sub_time) values("xxx",now());
END //
delimiter ;-- 在 mysql 中调用
call p1() -- 在 python 中基于 pymysql 调用
cursor.callproc('p1')
print(cursor.fetchall())
3.3 创建存储过程(有参)
存储过程的参数有三类:in仅用于传入参数,out仅用于返回值,inout既可以传入又可以当作返回值。
-- 示例 1:in 参数
delimiter //
create procedure p2(in n1 int,in n2 int
)
BEGINselect * from blog where id > n1;
END //
delimiter ;-- 在 mysql 中调用
call p2(3,2)-- 在 python 中基于 pymysql 调用
cursor.callproc('p2',(3,2))
print(cursor.fetchall())-- 示例 2:in 和 out 参数
delimiter //
create procedure p3(in n1 int,out res int
)
BEGINselect * from blog where id > n1;set res = 1;
END //
delimiter ;-- 在 mysql 中调用
set @res=0; -- 0代表假(执行失败),1代表真(执行成功)
call p3(3,@res);
select @res;-- 在 python 中基于 pymysql 调用
cursor.callproc('p3',(3,0)) -- 0相当于 set @res=0
print(cursor.fetchall()) -- 查询 select 的查询结果cursor.execute('select @_p3_0,@_p3_1;') -- @p3_0代表第一个参数,@p3_1代表第二个参数,即返回值
print(cursor.fetchall())-- 示例 3:inout 参数
delimiter //
create procedure p4(inout n1 int
)
BEGINselect * from blog where id > n1;set n1 = 1;
END //
delimiter ;-- 在 mysql 中调用
set @x=3;
call p4(@x);
select @x;-- 在 python 中基于 pymysql 调用
cursor.callproc('p4',(3,))
print(cursor.fetchall()) -- 查询 select 的查询结果cursor.execute('select @_p4_0;')
print(cursor.fetchall())
3.4 执行存储过程
-- 无参数
call proc_name()-- 有参数,全 in
call proc_name(1,2)-- 有参数,有 in,out,inout
set @t1=0;
set @t2=3;
call proc_name(1,2,@t1,@t2)
以下是 Python 中基于 pymysql 调用存储过程的示例:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysqlconn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 执行存储过程
cursor.callproc('p1', args=(1, 22, 3, 4))
# 获取执行完存储的参数
cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")
result = cursor.fetchall()conn.commit()
cursor.close()
conn.close()print(result)
3.5 删除存储过程
删除存储过程的语法为:drop procedure 存储过程名称。例如:
drop procedure proc_name;
四、函数
MySQL 提供了许多内置函数,以下是一些常见的函数分类和示例:
4.1 数学函数
- ROUND(x,y):返回参数 x 的四舍五入的有 y 位小数的值。
- RAND():返回 0 到 1 内的随机值,可以通过提供一个参数(种子)使 RAND() 随机数生成器生成一个指定的值。
4.2 聚合函数
- AVG(col):返回指定列的平均值。
- COUNT(col):返回指定列中非 NULL 值的个数。
- MIN(col):返回指定列的最小值。
- MAX(col):返回指定列的最大值。
- SUM(col):返回指定列的所有值之和。
- GROUP_CONCAT(col):返回由属于一组的列值连接组合而成的结果。
4.3 字符串函数
- CHAR_LENGTH(str):返回字符串 str 的长度,长度的单位为字符。
- CONCAT(str1,str2,…):字符串拼接,如有任何一个参数为 NULL,则返回值为 NULL。
- CONCAT_WS(separator,str1,str2,…):字符串拼接(自定义连接符),不会忽略任何空字符串,但会忽略所有的 NULL。
- CONV(N,from_base,to_base):进制转换。
- FORMAT(X,D):将数字 X 的格式写为 ‘#,###,###.##’,以四舍五入的方式保留小数点后 D 位,并将结果以字符串的形式返回。
- INSERT(str,pos,len,newstr):在 str 的指定位置插入字符串。
- INSTR(str,substr):返回字符串 str 中子字符串的第一个出现位置。
- LEFT(str,len):返回字符串 str 从开始的 len 位置的子序列字符。
- LOWER(str):变小写。
- UPPER(str):变大写。
- REVERSE(str):返回字符串 str,顺序和字符顺序相反。
- SUBSTRING(str,pos)、SUBSTRING(str FROM pos)、SUBSTRING(str,pos,len)、SUBSTRING(str FROM pos FOR len):从字符串 str 返回子字符串。
4.4 日期和时间函数
- CURDATE()或 CURRENT_DATE():返回当前的日期。
- CURTIME() 或 CURRENT_TIME():返回当前的时间。
- DAYOFWEEK(date):返回 date 所代表的一星期中的第几天(1~7)。
- DAYOFMONTH(date):返回 date 是一个月的第几天(1~31)。
- DAYOFYEAR(date):返回 date 是一年的第几天(1~366)。
- DAYNAME(date):返回 date 的星期名。
- FROM_UNIXTIME(ts,fmt):根据指定的 fmt 格式,格式化 UNIX 时间戳 ts。
- HOUR(time):返回 time 的小时值(0~23)。
- MINUTE(time):返回 time 的分钟值(0~59)。
- MONTH(date):返回 date 的月份值(1~12)。
- MONTHNAME(date):返回 date 的月份名。
- NOW():返回当前的日期和时间。
- QUARTER(date):返回 date 在一年中的季度(1~4)。
- WEEK(date):返回日期 date 为一年中第几周(0~53)。
- YEAR(date):返回日期 date 的年份(1000~9999)。
4.5 加密函数
在数据处理过程中,为了保证数据的安全性,常常需要对敏感信息进行加密处理。MySQL 提供了一些实用的加密函数。
4.5.1 MD5()
MD5()函数用于计算字符串的 MD5 校验和。MD5 是一种广泛使用的哈希函数,它可以将任意长度的输入转换为固定长度(128 位)的哈希值。示例如下:
SELECT MD5('your_string');
上述代码会返回 your_string 的 MD5 哈希值。
4.5.2 PASSWORD(str)
PASSWORD(str) 函数返回字符串 str 的加密版本,这个加密过程是不可逆转的,并且和 UNIX 密码加密过程使用不同的算法。通常用于存储用户密码,示例如下:
SELECT PASSWORD('your_password');
该代码会返回 your_password加密后的结果。
4.6 控制流函数
控制流函数可以根据不同的条件返回不同的结果,在数据处理和查询中非常有用。
4.6.1 CASE WHEN[test1] THEN [result1]…ELSE [default] END
这种形式的 CASE 语句用于根据多个条件进行判断。如果 testN为真,则返回 resultN,否则返回 default。示例如下:
SELECT CASE WHEN score >= 90 THEN '优秀'WHEN score >= 80 THEN '良好'WHEN score >= 60 THEN '及格'ELSE '不及格'END AS grade
FROM student_scores;
上述代码根据学生的成绩 score进行判断,返回对应的等级。
4.6.2 CASE [test] WHEN[val1] THEN [result]…ELSE [default]END
这种形式的 CASE语句用于判断 test是否等于 valN。如果相等,则返回 resultN,否则返回 default。示例如下:
SELECT CASE subjectWHEN '数学' THEN 'Math'WHEN '语文' THEN 'Chinese'ELSE 'Other'END AS subject_english
FROM courses;
该代码根据课程名称 subject` 返回对应的英文名称。
4.6.3 IF(test,t,f)
IF()函数根据 test 的真假返回不同的值。如果 test为真,返回 t;否则返回 f。示例如下:
SELECT IF(age >= 18, '成年人', '未成年人') AS age_group FROM users;
上述代码根据用户的年龄 age 判断其是否为成年人。
4.6.4 IFNULL(arg1,arg2)
IFNULL() 函数用于判断 arg1是否为空。如果arg1不是空,返回 arg1;否则返回 arg2。示例如下:
SELECT IFNULL(email, '未提供邮箱') AS user_email FROM users;
该代码在用户邮箱 email 为空时,返回 未提供邮箱`。
4.6.5 NULLIF(arg1,arg2)
NULLIF()函数用于比较 arg1 和 arg2。如果 arg1 = arg2,返回 NULL;否则返回 arg1。示例如下:
SELECT NULLIF(value1, value2) FROM data_table;
上述代码会根据 value1和 value2的比较结果返回相应的值。
4.7 控制流函数小练习
4.7.1 准备表
我们创建了几个表,包括 course、score、student 和 teacher,并插入了一些示例数据。以下是创建表和插入数据的 SQL 代码:
SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (`c_id` int(11) NOT NULL,`c_name` varchar(255) DEFAULT NULL,`t_id` int(11) DEFAULT NULL,PRIMARY KEY (`c_id`),KEY `t_id` (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', 'python', '1');
INSERT INTO `course` VALUES ('2', 'java', '2');
INSERT INTO `course` VALUES ('3', 'linux', '3');
INSERT INTO `course` VALUES ('4', 'web', '2');-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (`id` int(11) NOT NULL AUTO_INCREMENT,`s_id` int(10) DEFAULT NULL,`c_id` int(11) DEFAULT NULL,`num` double DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES ('1', '1', '1', '79');
INSERT INTO `score` VALUES ('2', '1', '2', '78');
INSERT INTO `score` VALUES ('3', '1', '3', '35');
INSERT INTO `score` VALUES ('4', '2', '2', '32');
INSERT INTO `score` VALUES ('5', '3', '1', '66');
INSERT INTO `score` VALUES ('6', '4', '2', '77');
INSERT INTO `score` VALUES ('7', '4', '1', '68');
INSERT INTO `score` VALUES ('8', '5', '1', '66');
INSERT INTO `score` VALUES ('9', '2', '1', '69');
INSERT INTO `score` VALUES ('10', '4', '4', '75');
INSERT INTO `score` VALUES ('11', '5', '4', '66.7');-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (`s_id` varchar(20) NOT NULL,`s_name` varchar(255) DEFAULT NULL,`s_age` int(10) DEFAULT NULL,`s_sex` char(1) DEFAULT NULL,PRIMARY KEY (`s_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '鲁班', '12', '男');
INSERT INTO `student` VALUES ('2', '貂蝉', '20', '女');
INSERT INTO `student` VALUES ('3', '刘备', '35', '男');
INSERT INTO `student` VALUES ('4', '关羽', '34', '男');
INSERT INTO `student` VALUES ('5', '张飞', '33', '女');-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (`t_id` int(10) NOT NULL,`t_name` varchar(50) DEFAULT NULL,PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('1', '张三');
INSERT INTO `teacher` VALUES ('2', 'lisi');
INSERT INTO `teacher` VALUES ('3', 'xiao');
INSERT INTO `teacher` VALUES ('4', 'peiqi');
4.7.2 统计各科各分数段人数
我们要统计各科各分数段的人数,显示格式为:课程 ID、课程名称、[100 - 85]、[85 - 70]、[70 - 60]、[ < 60]。可以使用以下 SQL 语句:
select score.c_id,course.c_name, sum(CASE WHEN num BETWEEN 85 and 100 THEN 1 ELSE 0 END) as '[100-85]',sum(CASE WHEN num BETWEEN 70 and 85 THEN 1 ELSE 0 END) as '[85-70]',sum(CASE WHEN num BETWEEN 60 and 70 THEN 1 ELSE 0 END) as '[70-60]',sum(CASE WHEN num < 60 THEN 1 ELSE 0 END) as '[ <60]'
from score,course where score.c_id=course.c_id GROUP BY score.c_id;
该 SQL 语句通过 CASE语句对分数进行分段统计,并使用 SUM()函数计算每个分数段的人数。
五、自定义函数
在 MySQL 中,我们可以自定义函数来实现特定的功能。需要注意的是,函数中不要写 SQL 语句,函数仅仅只是一个功能,是一个在 SQL 中被应用的功能。若要想在 begin…end… 中写 SQL,请用存储过程。
5.1 创建自定义函数
以下是两个自定义函数的示例:
delimiter //
create function f1(i1 int,i2 int)
returns int
BEGINdeclare num int;set num = i1 + i2;return(num);
END //
delimiter ;delimiter //
create function f5(i int
)
returns int
begindeclare res int default 0;if i = 10 thenset res=100;elseif i = 20 thenset res=200;elseif i = 30 thenset res=300;elseset res=400;end if;return res;
end //
delimiter ;
f1函数用于计算两个整数的和,f5 函数根据输入的整数返回不同的结果。
5.2 删除函数
如果不再需要某个自定义函数,可以使用 DROP FUNCTION语句将其删除,示例如下:
drop function func_name;
其中 func_name是要删除的函数名。
5.3 执行函数
可以通过以下方式执行自定义函数:
-- 获取返回值
select UPPER('xiao') into @res;
SELECT @res;-- 在查询中使用
select f1(11,nid) ,name from tb2;
上述代码展示了如何获取函数的返回值以及在查询中使用函数。
六、流程控制
MySQL 提供了多种流程控制语句,如条件语句和循环语句。
6.1 条件语句
以下是一个使用 IF语句的存储过程示例:
delimiter //
CREATE PROCEDURE proc_if ()
BEGINdeclare i int default 0;if i = 1 THENSELECT 1;ELSEIF i = 2 THENSELECT 2;ELSESELECT 7;END IF;END //
delimiter ;
该存储过程根据变量 i的值返回不同的结果。
5.2 循环语句
6.2.1 WHILE 循环
delimiter //
CREATE PROCEDURE proc_while ()
BEGINDECLARE num INT ;SET num = 0 ;WHILE num < 10 DOSELECTnum ;SET num = num + 1 ;END WHILE ;END //
delimiter ;
该存储过程使用 WHILE循环,当 num 小于 10 时,不断输出 num的值并将其加 1。
6.2.2 REPEAT 循环
delimiter //
CREATE PROCEDURE proc_repeat ()
BEGINDECLARE i INT ;SET i = 0 ;repeatselect i;set i = i + 1;until i >= 5end repeat;END //
delimiter ;
该存储过程使用 REPEAT 循环,先执行循环体,然后判断条件,直到 i 大于等于 5 时停止循环。
6.2.3 LOOP 循环
BEGINdeclare i int default 0;loop_label: loopset i=i+1;if i<8 theniterate loop_label;end if;if i>=10 thenleave loop_label;end if;select i;end loop loop_label;END
结语
通过这个21天的Python计划,我们涵盖了MySQL视图、触发器、存储过程、函数与流程控制。希望这些内容能帮助你更好地理解和使用Python。继续学习和实践,你将成为一名优秀的Python开发者!
📢 注意啦!文末有彩蛋!参与评论就有机会把这本好书抱回家~动动手指,说不定下个锦鲤就是你!赠书福利
相关文章:
21 天 Python 计划:MySQL视图、触发器、存储过程、函数与流程控制
文章目录 一、视图1.1 创建视图1.2 使用视图1.3 修改视图1.4 删除视图 二、触发器2.1 创建触发器2.2 使用触发器2.3 删除触发器 三、存储过程3.1 介绍3.2 创建简单存储过程(无参)3.3 创建存储过程(有参)3.4 执行存储过程3.5 删除存…...
机器学习 Day10 逻辑回归
1.简介 流程就是: 就是我们希望回归后激活函数给出的概率越是1和0. 2.API介绍 sklearn.linear_model.LogisticRegression 是 scikit-learn 库中用于实现逻辑回归算法的类,主要用于二分类或多分类问题。以下是对其重要参数的详细介绍: 2.1.…...
Hadoop的序列化和反序列化
//1 package com.example.sei;import org.apache.hadoop.io.Writable;import java.io.DataInput; import java.io.DataOutput; import java.io.IOException;//学生类,姓名,年龄 //支持hadoop的序列化 //1.要实现Writable接口 //2.补充一个空参构造 publi…...
Altera Cyclone EP1C20F400C8N FPGA 阿尔特拉 介绍
在可编程逻辑器件领域,Altera 的 Cyclone 系列 FPGA 以其低成本、低功耗和灵活的 I/O 支持而著称。EP1C20F400C8N 作为 Cyclone I 家族中规模最大的成员之一,提供约 20 060 个逻辑单元,面向通信、工业控制、视频处理等多种嵌入式应用场景。…...
VTK随笔十四:QT与VTK的交互示例(平移)
VTK(Visualization Toolkit)是一个开源的软件系统,用于三维计算机图形学、图像处理和可视化。它提供了丰富的工具和类来处理三维数据和交互。在 VTK 中,拾取操作通常通过 vtkCellPicker 或 vtkPointPicker 等类来实现。 本文将展示…...
用户注册(阿里云手机验证码)
阿里云开通三网106短信 ①、在阿里云市场搜索“短信”,开通三网短信,并可以查看其中的请求示例(java PHP^) 并在个人中心的管理控制台中查到,获取其中的AppKey AppCode ②、接口开发 service-user模块中依赖spr…...
【BFT帝国】20250409更新PBFT总结
2411 2411 2411 Zhang G R, Pan F, Mao Y H, et al. Reaching Consensus in the Byzantine Empire: A Comprehensive Review of BFT Consensus Algorithms[J]. ACM COMPUTING SURVEYS, 2024,56(5).出版时间: MAY 2024 索引时间(可被引用): 240412 被引:…...
学习海康VisionMaster之边缘交点
一:进一步学习了 今天学习下VisionMaster中的边缘交点,这个还是拟合直线的衍生应用,可以同时测量两条直线并且输出交点或者判定是否有交点 二:开始学习 1:什么是边缘交点? 按照传统的算法,必须…...
公司级项目-AD9914扫频源(三)评估板与上位机的初步调试
硬件平台搭建1-评估板与上位机 第一阶段,先使用评估板配套的上位机软件进行控制,学习一下各种功能的实现方式和寄存器配置方式。 硬件连接 需要的设备仪器包括:多路直流稳压电源、信号发生器、示波器、电脑。 按照图中的方式进行连接&am…...
技术优化实战解析:Stream重构与STAR法则应用指南
目录 一、真实案例背景:老代码的"历史厚重感" 二、屎山代码解剖课:这些写法到底烂在哪? 三、Stream流式重构:给老代码做个大保健 2.1 重构后代码实现 2.2 核心API技术拆解 2.3 进阶优化技巧 三、STAR法则技术文档…...
基于Qt的串口通信工具
程序介绍 该程序是一个基于Qt的串口通信工具,专用于ESP8266 WiFi模块的AT指令配置与调试。主要功能包括: 1. 核心功能 串口通信:支持串口开关、参数配置(波特率、数据位、停止位、校验位)及数据收发。 AT指令操作&a…...
Xilinx FPGA XCZU5EV‑2FBVB900I Zynq UltraScale+™ MPSoC EV 系列
XCZU5EV‑1FBVB900I XCZU5EV‑2FBVB900E XCZU5EV‑1FBVB900I 是 Xilinx Zynq UltraScale™ MPSoC EV 系列中功能最为丰富的器件之一,采用 16 nm FinFET 工艺,封装为 31 mm 31 mm、900‑ball FCBGA(FBVB900)。该系列在传统的…...
如何更改OCP与metadb集群的连接方式 —— OceanBase运维管理
背景 许多用户都会借助OCP平台来进行OceanBase集群的运维与监控,且因为考虑单节点的OCP部署,在遇故障时可能会短时间出现无法管控 OceanBase集群,多数用户倾向于采用多节点方式来部署OCP,即 OCP的 metadb集群也是三节点的集群部署…...
Databricks: Why did your cluster disappear?
You may found that you created a cluster many days ago, and you didnt delete it, but it is disapear. Why did this happen? Who deleted the cluster? Actually, 30 days after a compute is terminated, it is permanently deleted automaticlly. If your workspac…...
深入解析Java内存与缓存:从原理到实践优化
一、Java内存管理:JVM的核心机制 1. JVM内存模型全景图 ┌───────────────────────────────┐ │ JVM Memory │ ├─────────────┬─────────────────┤ │ Thread │ 共享…...
macos下 ragflow二次开发环境搭建
参考官网链接 https://ragflow.io/docs/dev/launch_ragflow_from_source虚拟环境 git clone https://github.com/infiniflow/ragflow.git cd ragflow/ # if not pipx, please install it at first pip3 install pipxpipx install uv uv sync --python 3.10 --all-extras 安装 …...
从 Excel 到你的表格应用:条件格式功能的嵌入实践指南
一、引言 在日常工作中,面对海量数据时,如何快速识别关键信息、发现数据趋势或异常值,是每个数据分析师面临的挑战。Excel的条件格式功能通过自动化的视觉标记,帮助用户轻松应对这一难题。 本文将详细介绍条件格式的应用场景&am…...
安徽京准:NTP网络时钟服务器功能及同步模式的介绍
安徽京准:NTP网络时钟服务器功能及同步模式的介绍 安徽京准:NTP网络时钟服务器功能及同步模式的介绍 1、NTP网络时钟服务器概念: NTP时钟服务器,表面意思是时间计量工具的服务设备,其在现代工业中是用于对客户端设备…...
基于ueditor编辑器的功能开发之百度编辑器自带的查找和替换功能无法对目标文字进行滚动定位修复
在查找百度编辑器的查找和替换功能,发现当页面文字过多,用户在检索文字点击上一个下一个的时候,滚动条不跟随滚动了 分析了ueditor关于searchpalce方法的处理时,他会在目标文字的前面插入一个span标签用户获取当前需要高亮的文字节…...
MYSQL——SQL语句到底怎么执行
查询语句执行流程 MySQL 查询语句执行流程 查询缓存(Query Cache) MySQL内部自带了一个缓存模块,默认是关闭的。主要是因为MySQL自带的缓存应用场景有限。 它要求SQL语句必须一摸一样表里面的任何一条数据发生变化时,该表所有缓…...
[蓝桥杯 2022 省 B] 李白打酒加强版
题目链接: 思路: ①定义dp数组,f[i][j][k],表示经过 i 店, 遇到 j 花, 还有 k 酒。如果酒的数量超过了花的数量,那么一定喝不完。因此,k 不能超过 M。 ②从店推过来,f[…...
计算机视觉——图像金字塔与目标图像边缘检测原理与实践
一、两个图像块之间的相似性或距离度量 1.1 平方差和(SSD) 平方差和(SSD) 是一种常用的图像相似性度量方法。它通过计算两个图像在每个对应位置的像素值差的平方和来衡量两个图像之间的整体差异。如果两个图像在每个位置的像素值…...
复现QGIS-MCP教程
由于Claude国内下载不了尝试使用Cursor 下载安装Cursor Cursor - The AI Code Editor 本示例安装的是0.46版本 UV安装 简介 安装 安装成功 配置环境变量 验证 下载代码 git clone gitgithub.com:jjsantos01/qgis_mcp.git QGIS插件安装 文件拷贝 您需要将 qgis_mcp_plu…...
人工智能图像识别Spark Core
Spark Core 一.spark运行架构 1.运行架构 Spark 框架的核心是一个计算引擎,整体来说,它采用了标准 master-slave 的结构。 如下图所示,它展示了一个 Spark 执行时的基本结构。图形中的 Driver 表示 master,负责管理整个集群中的作…...
决策树+泰坦尼克号生存案例
决策树简介 学习目标 1.理解决策树算法的基本思想 2.知道构建决策树的步骤 【理解】决策树例子 决策树算法是一种监督学习算法,英文是Decision tree。 决策树思想的来源非常朴素,试想每个人的大脑都有类似于if-else这样的逻辑判断,这其中…...
怎么查看苹果手机和ipad的设备信息和ios udid
你知道吗?我们每天使用的iPhone和iPad,其实隐藏着大量详细的硬件与系统信息。除了常见的系统版本和序列号外,甚至连电池序列号、摄像头序列号、销售地区、芯片型号等信息,也都可以轻松查到! 如果你是开发者、维修工程…...
智能驱动教育变革:人工智能在高中教育中的实践路径与创新策略
一、引言 随着信息技术的飞速发展,人工智能(Artificial Intelligence, AI)已成为推动社会进步的重要力量。在教育领域,人工智能的应用正逐渐改变着传统的教学模式和方法,为教育现代化注入了新的活力。高中教育作为教育…...
TCP 和 UDP 可以使用同一个端口吗?
TCP 和 UDP 可以使用同一个端口吗? 前言 在深入探讨 TCP 和 UDP 是否可以使用同一个端口之前,我们首先需要理解网络通信的基本原理。网络通信是一个复杂的过程,涉及到多个层次的协议和机制。在 OSI 模型中,传输层是负责端到端数…...
MySQL事务管理
MySQL事务管理 事务的概念 事务由一条或多条SQL语句组成,这些语句在逻辑上存在相关性,共同完成一个任务,事务主要用于处理操作量大,复杂度高的数据。比如转账就涉及多条SQL语句,包括查询余额(select&…...
通过 SSH 方式访问 GitHub 仓库
我们来一步一步讲解如何让 Git 通过 SSH 方式访问 GitHub 仓库,包括从零开始的详细步骤,适用于大多数系统(Linux、macOS、Windows Git Bash)。 注意最好只用 Git bash 比较好!他能够直接在 Windows 系统上面使用一些 L…...
数据库学习
DDL(数据定义语言)、DML(数据操纵语言)、DQL(数据查询语言)和DCL(数据控制语言)。 DDL用于创建、删除和修改数据库对象,如表和数据库;DML涉及数据的增删改操…...
DeepSeek在安全领域的应用案例全景解析
DeepSeek作为人工智能领域的标杆技术,已在网络安全、公共安全、工业安全、军事防护等领域形成系统性应用。以下从六大核心场景展开分析,结合技术实现与行业标杆案例,呈现其多维度的安全赋能价值。 一、网络安全防护体系创新 威胁检测与响应闭环安胜"星盾"平台:通…...
AI驱动SEO关键词精准定位
内容概要 在传统SEO实践中,关键词定位往往依赖人工经验与有限的数据样本,导致策略滞后性与覆盖盲区并存。随着AI技术的深度介入,这一过程正经历系统性重构:从搜索意图的智能识别到关键词的自动化挖掘,算法模型通过分析…...
邮件营销:如何巧妙平衡发送频率与客户体验
在邮件营销领域,发送频率和客户体验就像跷跷板的两端,需要精心平衡。如果邮件发得太多,客户可能会觉得烦,甚至取消订阅,对品牌产生不好的印象;但如果发得太少,客户又容易把你忘了,错…...
Acrel-1000DP分布式光伏监控系统在嘉兴亨泰新能源有限公司2996.37KWP分布式光伏项目中的应用
摘 要:分布式光伏发电系统其核心特点是发电设备靠近用电负荷中心,通常安装在屋顶、建筑立面或闲置空地上,截至2025年,分布式光伏发电系统在全球和中国范围内取得了显著发展,成为能源转型和可持续发展的重要推动力量。国…...
vue3中左右布局两个个组件使用vuedraggable实现左向右拖动,右组件列表可上下拖动
需求:左侧是个菜单组件,有对应的表单类型。 右侧是渲染组件,点击左侧菜单或者拖动即可渲染出对应的组件 项目中采用vuedraggable实现拖拽功能。 具体实现是使用elementplus的组件,然后根据tagName的类型去渲染不同的组件。 首先…...
gevent 高并发、 RabbitMQ 消息队列、Celery 分布式的案例和说明
1. gevent 高并发请求示例 gevent:基于协程的Python库,通过异步非阻塞模式实现高并发请求。例如,同时抓取100个网页时,无需等待每个请求完成,提升效率。 import gevent from gevent import monkey monkey.patch_…...
直线模组在电子行业具体的应用
在工业自动化高速发展的今天,直线模组作为重要的传动和控制元件,凭借其高效、精准、稳定的特性。在众多行业中得到了广泛应用,尤其是在电子行业中,通过提供精确的运动控制和定位,帮助提高电子制造过程的效率、质量和自…...
Ubuntu 24.04启用root账户
1.启用ubuntu中的root账号 ubuntu默认是禁用了root账号的,需要手动开始root权限 # 设置root账号密码 sudo passwd root # 用以下命令启用 root 账户: sudo usermod -aG sudo rootsu - root 然后输入你之前设置的 root 密码。 一旦你成功登录为 root 用户&#x…...
【ES系列】Elasticsearch简介:为什么需要它?(基础篇)
🔥 本文将详细介绍Elasticsearch的前世今生,以及为什么它在当今的技术栈中如此重要。本文是ES起飞之路系列的基础篇第一章,适合想要了解ES的读者。 文章目录 一、什么是Elasticsearch?1. ES的定义2. ES的核心特性2.1 分布式存储2.2 实时搜索2.3 高可用性2.4 RESTful API3.…...
SvelteKit 最新中文文档教程(19)—— 最佳实践之身份认证
前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1: Svelte …...
Droris(强制)删除某一个分区数据
Doris如果想删除某一个分区的数据,可以这么操作: DROP PARTITION [IF EXISTS] partition_name [FORCE]需要注意的是: 必须为使用分区的表保留至少一个分区。执行DROP PARTITION一段时间后,可以通过RECOVER语句恢复被删除的分区:…...
Meta 最新 AI 模型系列 ——Llama 4
Meta 发布了最新 AI 模型系列 ——Llama 4,这是其 Llama 家族的最新成员。 在大模型竞技场(Arena),Llama 4 Maverick 的总排名第二,成为第四个突破 1400 分的大模型。其中开放模型排名第一,超越了 DeepSeek…...
软考 系统架构设计师系列知识点 —— 设计模式之工厂模式
本文内容参考: 软考 系统架构设计师系列知识点之设计模式(2)_系统架构设计师中考设计模式吗-CSDN博客 https://baike.baidu.com/item/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F?fromModulelemma_search-box 设计模式-工厂方法模式࿰…...
Jetpack Compose 状态保存机制全面解析:让UI状态持久化
在Android开发中,Jetpack Compose 的状态管理是一个核心话题,而状态保存则是确保良好用户体验的关键。本文将深入探讨Compose中各种状态保存技术,帮助你在配置变更和进程重建时保持UI状态。 一、基础保存:rememberSaveable reme…...
阿里云原生AI网关Higress:架构解析与应用实践
摘要 随着云原生与AI技术的深度融合,API网关作为流量治理的核心组件,正面临新的挑战与机遇。阿里云开源的Higress网关,凭借其“三网合一”(流量网关、微服务网关、安全网关)的高集成能力,以及面向AI场景的…...
如何在数据仓库中集成数据共享服务?
目录 1. Snowflake 数据共享服务:云端的最佳实践 2. 数据共享服务的重要性 3. 麦聪 QuickAPI:企业本地的理想选择 4. 云端与本地的互补 总结 数据共享服务是现代数据仓库的核心功能,能够提升协作效率、降低成本并释放数据潜力。 以 Sno…...
spark RDD相关概念和运行架构
核心概念 - RDD定义:弹性分布式数据集,是Spark中基础数据处理抽象,具弹性、不可变、可分区及并行计算特性。 弹性 存储的弹性:内存与磁盘的自动切换; 容错的弹性:数据丢失可以自动恢复; 计算…...
2025.04.09【Sankey】| 生信数据流可视化精讲
文章目录 引言Sankey图简介R语言中的Sankey图实现安装和加载networkD3包创建Sankey图的数据结构创建Sankey图绘制Sankey图 结论 引言 在生物信息学领域,数据可视化是理解和分析复杂数据集的关键工具之一。今天,我们将深入探讨一种特别适用于展示数据流动…...
《系统分析师-案例实践篇-16-22章总结》
案例实践篇...