当前位置: 首页 > news >正文

【MySQL学习】存储过程

目录

一、定义

二、基本语法

1.创建存储过程

2.删除存储过程

3.查看存储过程

三、控制语句

1.变量声明与赋值

四、游标(Cursor)

(1)声明游标

 (2)处理游标结束

(3)打开游标

(4)读取数据

(5)关闭景点

五、案例语句

1.值匹配

2.条件匹配

五、综合案例

第一步:创建表

第二步:创建存储过程:ProcessStudentGrades

第三步:测试


一、定义

存储过程是一组预编译的 SQL 语句集合,经过编译后存储在数据库服务器上。

可以把它想象成数据库中的一个自定义函数或脚本。

主要用于封装常用的、复杂的或重复性的数据库操作,简化应用程序开发,提高性能和安全性。

二、基本语法

1.创建存储过程

DELIMITER //
CREATE PROCEDURE procedure_name ([parameter_list])
BEGIN-- SQL 语句
END //
DELIMITER ;

(1)DELIMITER //  和  DELIMITER ;

存储过程内部通常包含分号 (;) 作为 SQL 语句的结束符,为了让 MySQL 客户端能够区分存储过程定义的结束 (END) 和内部 SQL 语句的结束,需要临时改变语句结束符(常用 //$$),定义完毕后再改回默认的分号 (;)。

(2) parameter_list:参数列表(可选),可以是输入、输出或输入输出参数。

  • IN: 输入参数(默认模式)。值由调用者传入存储过程,在过程中只读。
  • OUT: 输出参数。值在存储过程中被设置,并可以返回给调用者。调用时传入的变量会被修改。
  • INOUT: 输入输出参数。调用者传入初始值,存储过程可以读取和修改它,修改后的值可以返回给调用者。

示例1:计算公司给定部门的总人数

DELIMITER //
CREATE PROCEDURE get_employee_count_by_dept(IN dept_id INT, OUT emp_count INT)
BEGINSELECT COUNT(*) INTO emp_countFROM employeesWHERE department_id = dept_id;
END //
DELIMITER ;
CALL get_employee_count_by_dept(10, @count); 
SELECT @count; 

CALL get_employee_count_by_dept(10, @count); -- 将部门 10 的员工数放入 @count 变量

示例2:给定num,计算num+1的值

CREATE PROCEDURE increment(INOUT num INT)
BEGINSET num = num + 1;
END //
SET @value = 10;
CALL increment(@value);
SELECT @value; 

2.删除存储过程

DROP PROCEDURE [IF EXISTS] procedure_name;
使用 IF EXISTS避免因存储过程不存在而报错

3.查看存储过程

(1)查看数据库中的存储过程列表
SHOW PROCEDURE STATUS [WHERE condition];

示例1:

SHOW PROCEDURE STATUS;
  • 说明:没有WHERE子句,启动当前用户有权限访问的所有存储过程的信息。
  • 结果:返回所有存储过程的元数据,可能包含多个数据库中的存储过程。

示例二:

SHOW PROCEDURE STATUS WHERE Db = 'AlinJ';

(2)查看存储过程定义

SHOW CREATE PROCEDURE procedure_name;

三、控制语句

1.变量声明与赋值

(1)变量声明

在存储过程中定义局部变量,用于存储临时数据

DECLARE variable_name data_type [DEFAULT value];
  • 变量声明必须位于BEGIN ... END块的开头,且位于任何其他语句之前。
  • 变量的作用域仅限于当前BEGIN ... END块,块结束后变量自动推理。

(2)变量赋值

方法一:SET语句

SET variable_name = ALinJ;

方法二:SELECT ... INTO 语句

SELECT column_name INTO variable_name FROM table_name WHERE condition;

示例:将employees表中id为1的员工的姓名赋给变量

SELECT name INTO @emp_name FROM employees WHERE id = 1;
SELECT @emp_name;

(3)示例:统计用户表中用户数量,并根据数量进行状态设置。

DELIMITER //
CREATE PROCEDURE count_users()
BEGINDECLARE total_users INT DEFAULT 0;DECLARE user_status VARCHAR(20);SELECT COUNT(*) INTO total_users FROM users;SET user_status = IF(total_users > 100, 'High', 'Low');SELECT total_users AS 'Total Users', user_status AS 'User Status';
END //
DELIMITER ;CALL count_users();

2. 条件语句(IF-ELSE)

IF condition THEN-- 语句
ELSEIF condition THEN-- 语句
ELSE-- 语句
END IF;

示例1:根据用户分数判断是否及格

DELIMITER //
CREATE PROCEDURE check_score(IN score INT, OUT result VARCHAR(20))
BEGINIF score >= 60 THENSET result = 'Pass';ELSESET result = 'Fail';END IF;SELECT result AS 'Result';
END //
DELIMITER ;CALL check_score(75, @result);

示例2:根据分数评定等级(A、B、C)

DELIMITER //
CREATE PROCEDURE grade_score(IN score INT, OUT grade VARCHAR(10))
BEGINIF score >= 90 THENSET grade = 'A';ELSEIF score >= 75 THENSET grade = 'B';ELSEIF score >= 60 THENSET grade = 'C';ELSESET grade = 'Fail';END IF;SELECT grade AS 'Grade';
END //
DELIMITER ;CALL grade_score(85, @grade);

示例3:检查分数是否有效,并评估等级

DELIMITER //
CREATE PROCEDURE validate_score(IN score INT, OUT message VARCHAR(50))
BEGINIF score < 0 OR score > 100 THENSET message = 'Invalid score';ELSEIF score >= 60 THENSET message = 'Pass';ELSESET message = 'Fail';END IF;END IF;SELECT message AS 'Message';
END //
DELIMITER ;CALL validate_score(-10, @message);

3. 循环语句

(1)WHILE 循环

WHILE condition DO-- 语句
END WHILE;
  • 条件为真时执行循环体。
  • 条件在循环开始前检查,可能一次都不执行。

示例:插入 1 到 5 的数字到表中。

CREATE TABLE numbers (num INT);DELIMITER //
CREATE PROCEDURE insert_numbers()
BEGINDECLARE i INT DEFAULT 1;WHILE i <= 5 DOINSERT INTO numbers VALUES (i);SET i = i + 1;END WHILE;SELECT * FROM numbers;
END //
DELIMITER ;CALL insert_numbers();

(2)REPEAT 循环

REPEAT-- 语句
UNTIL condition
END REPEAT;
  • 先执行循环体,再检查条件。
  • 至少执行一次,条件为真时退出循环。
示例:计算 1 到 5 的累加和。
DELIMITER //
CREATE PROCEDURE calculate_sum(OUT total INT)
BEGINDECLARE i INT DEFAULT 1;SET total = 0;REPEATSET total = total + i;SET i = i + 1;UNTIL i > 5END REPEAT;SELECT total AS 'Total Sum';
END //
DELIMITER ;CALL calculate_sum(@total);

(3)LOOP 循环

[label:] LOOP-- 语句IF condition THENLEAVE label; -- 相当于breakEND IF;-- ITERATE label; -- 相当于continue
END LOOP [label];
  • 无条件循环,必须通过LEAVE语句退出。
  • ITERATE语句可跳到下一次循环。
  • label是可选的循环标签,用于LEAVE和ITERATE。

示例1:插入 1 到 5 的数字,并跳过 3

DELIMITER //
CREATE PROCEDURE insert_numbers_with_skip()
BEGINDECLARE i INT DEFAULT 1;my_loop: LOOPIF i > 5 THENLEAVE my_loop;END IF;IF i = 3 THENSET i = i + 1;ITERATE my_loop;END IF;INSERT INTO numbers VALUES (i);SET i = i + 1;END LOOP my_loop;SELECT * FROM numbers;
END //
DELIMITER ;CALL insert_numbers_with_skip();

四、游标(Cursor)

游标是 MySQL 存储过程中用于处理查询结果集的工具,允许逐行读取和操作查询结果。

基本使用步骤:

  • 声明指标:用于存储游标读取的数据和控制循环的标志。
  • 声明游标:绑定一个SELECT语句。
  • 声明HANDLER:处理游标读取结束。
  • 打开景点。
  • 循环读取数据:用FETCH读取每一行,处理逻辑。
  • 关闭游标。

(1)声明游标

CLOSE cursor_name;
DECLARE cursor_name CURSOR FOR select_statement;
  • 游标必须绑定一个SELECT语句。
  • 声明必须在存储过程的BEGIN ... END块开头,在变量声明之后。

 (2)处理游标结束

  • 问题:当游标读取到最后一行后,继续FETCH会导致错误。
  • 解决方法:使用HANDLER处理NOT FOUND条件。
DECLARE CONTINUE HANDLER FOR NOT FOUND SET variable = value;

(3)打开游标

OPEN cursor_name;
  • 游标后,MySQL 会执行SELECT语句,并将结果集加载到内存中。
  • 此时游标指向结果集的第一行之前。

(4)读取数据

从游标中读取一行数据,将数据存储到指定的变量中。

FETCH cursor_name INTO variable_list;

(5)关闭景点

CLOSE cursor_name;

示例1:遍历用户表,记录每个用户的ID和名称到日志表

第一步:准备数据

CREATE TABLE users (id INT, name VARCHAR(50));
CREATE TABLE logs (log_id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(100));INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie');

第二步:创建存储过程

DELIMITER //
CREATE PROCEDURE log_users()
BEGIN-- 声明变量DECLARE done INT DEFAULT 0;DECLARE u_id INT;DECLARE u_name VARCHAR(50);-- 声明游标DECLARE cur CURSOR FOR SELECT id, name FROM users;-- 声明 HANDLERDECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;-- 打开游标OPEN cur;-- 循环读取read_loop: LOOPFETCH cur INTO u_id, u_name;IF done THENLEAVE read_loop;END IF;-- 插入日志INSERT INTO logs (message) VALUES (CONCAT('User: ', u_id, ', Name: ', u_name));END LOOP read_loop;-- 关闭游标CLOSE cur;-- 查看结果SELECT * FROM logs;
END //
DELIMITER ;

第三步:调用

CALL log_users();

示例二:遍历用户表,给分数低于60的用户加10分,并记录操作日志。

第一步:准备数据

CREATE TABLE users (id INT, name VARCHAR(50), score INT);
CREATE TABLE logs (log_id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(100), log_time DATETIME);INSERT INTO users VALUES (1, 'Alice', 50), (2, 'Bob', 70), (3, 'Charlie', 45);

第二步:创建存储过程

DELIMITER //
CREATE PROCEDURE update_scores()
BEGINDECLARE done INT DEFAULT 0;DECLARE u_id INT;DECLARE u_score INT;DECLARE cur CURSOR FOR SELECT id, score FROM users;DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;OPEN cur;update_loop: LOOPFETCH cur INTO u_id, u_score;IF done THENLEAVE update_loop;END IF;-- 检查分数是否低于 60IF u_score < 60 THENSET u_score = u_score + 10;UPDATE users SET score = u_score WHERE id = u_id;INSERT INTO logs (message, log_time) VALUES (CONCAT('User ', u_id, ' score updated to ', u_score), NOW());END IF;END LOOP update_loop;CLOSE cur;SELECT * FROM users;SELECT * FROM logs;
END //
DELIMITER ;

第三步:调用

CALL update_scores();

示例3:将users表中的数据迁移到users_backup表,跳过分数低于50的用户。

第一步:准备数据

CREATE TABLE users (id INT, name VARCHAR(50), score INT);
CREATE TABLE users_backup (id INT, name VARCHAR(50), score INT);INSERT INTO users VALUES (1, 'Alice', 50), (2, 'Bob', 70), (3, 'Charlie', 40);

第二步:创建存储过程

DELIMITER //
CREATE PROCEDURE backup_users()
BEGINDECLARE done INT DEFAULT 0;DECLARE u_id INT;DECLARE u_name VARCHAR(50);DECLARE u_score INT;DECLARE cur CURSOR FOR SELECT id, name, score FROM users;DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;OPEN cur;backup_loop: LOOPFETCH cur INTO u_id, u_name, u_score;IF done THENLEAVE backup_loop;END IF;-- 跳过分数低于 50 的用户IF u_score < 50 THENITERATE backup_loop;END IF;-- 插入到备份表INSERT INTO users_backup VALUES (u_id, u_name, u_score);END LOOP backup_loop;CLOSE cur;SELECT * FROM users_backup;
END //
DELIMITER ;

第三步:调用

CALL backup_users();

五、案例语句

1.值匹配

CASE expressionWHEN value1 THEN-- 语句WHEN value2 THEN-- 语句[ELSE-- 语句]
END CASE;

示例:根据用户等级设置描述。

DELIMITER //
CREATE PROCEDURE describe_level(IN level CHAR(1), OUT description VARCHAR(20))
BEGINCASE levelWHEN 'A' THENSET description = 'Excellent';WHEN 'B' THENSET description = 'Good';WHEN 'C' THENSET description = 'Average';ELSESET description = 'Unknown';END CASE;SELECT description AS 'Description';
END //
DELIMITER ;CALL describe_level('B', @description);

2.条件匹配

CASEWHEN condition1 THEN-- 语句WHEN condition2 THEN-- 语句[ELSE-- 语句]
END CASE;

示例:根据分数评定等级。

DELIMITER //
CREATE PROCEDURE grade_score_case(IN score INT, OUT grade VARCHAR(10))
BEGINCASEWHEN score >= 90 THENSET grade = 'A';WHEN score >= 75 THENSET grade = 'B';WHEN score >= 60 THENSET grade = 'C';ELSESET grade = 'Fail';END CASE;SELECT grade AS 'Grade';
END //
DELIMITER ;CALL grade_score_case(85, @grade);

五、综合案例

我将创建一个存储过程ProcessStudentGrades,用于管理学生的成绩数据,支持以下功能:

  • 批量更新成绩(加分或减分)。
  • 根据成绩评定等级(A、B、C、Fail)。
  • 记录操作日志(例如,谁的成绩被更新、等级如何)。
  • 如果操作失败,记录错误日志。

第一步:创建表

CREATE TABLE students (id INT PRIMARY KEY,name VARCHAR(50),grade INT
);CREATE TABLE logs (log_id INT AUTO_INCREMENT PRIMARY KEY,message VARCHAR(255),log_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);INSERT INTO students (id, name, grade)
VALUES (1, 'Alice', 85),(2, 'Bob', 55),(3, 'Charlie', 92);

第二步:创建存储过程:ProcessStudentGrades

DELIMITER //CREATE PROCEDURE ProcessStudentGrades(IN action VARCHAR(20),  -- 操作类型:ADD(加分)、SUBTRACT(减分)、GRADE(评定等级)IN score_change INT,    -- 分数变化值(加分或减分)OUT result_message VARCHAR(100) 
)
BEGIN-- 声明变量DECLARE done INT DEFAULT 0;DECLARE s_id INT;DECLARE s_name VARCHAR(50);DECLARE s_grade INT;DECLARE new_grade INT;DECLARE grade_level VARCHAR(10);DECLARE loop_counter INT DEFAULT 0;-- 声明游标DECLARE cur CURSOR FOR SELECT id, name, grade FROM students;-- 声明游标结束处理器DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;-- 声明错误处理器DECLARE EXIT HANDLER FOR SQLEXCEPTIONBEGINSET result_message = 'Error occurred during operation.';INSERT INTO logs (message) VALUES (CONCAT('Error: ', result_message, ' during action: ', action));END;SET result_message = 'Operation completed successfully.';-- 使用 CASE 语句处理操作类型CASE UPPER(action)WHEN 'ADD' THEN-- 使用游标遍历学生,加分OPEN cur;add_loop: LOOPFETCH cur INTO s_id, s_name, s_grade;IF done THENLEAVE add_loop;END IF;-- 计算新分数SET new_grade = s_grade + score_change;-- 确保分数在 0-100 范围内IF new_grade > 100 THENSET new_grade = 100;END IF;-- 更新分数UPDATE students SET grade = new_grade WHERE id = s_id;INSERT INTO logs (message) VALUES (CONCAT('Student ', s_name, ' (ID: ', s_id, ') grade updated from ', s_grade, ' to ', new_grade));END LOOP add_loop;CLOSE cur;WHEN 'SUBTRACT' THEN-- 使用 WHILE 循环遍历学生,减分SET done = 0; OPEN cur;WHILE NOT done DOFETCH cur INTO s_id, s_name, s_grade;IF done THENLEAVE;END IF;-- 计算新分数SET new_grade = s_grade - score_change;-- 确保分数在 0-100 范围内IF new_grade < 0 THENSET new_grade = 0;END IF;-- 更新分数UPDATE students SET grade = new_grade WHERE id = s_id;INSERT INTO logs (message) VALUES (CONCAT('Student ', s_name, ' (ID: ', s_id, ') grade updated from ', s_grade, ' to ', new_grade));END WHILE;CLOSE cur;WHEN 'GRADE' THEN-- 使用 REPEAT 循环遍历学生,评定等级SET done = 0; OPEN cur;REPEATFETCH cur INTO s_id, s_name, s_grade;IF NOT done THEN-- 使用 IF-ELSE 评定等级IF s_grade >= 90 THENSET grade_level = 'A';ELSEIF s_grade >= 75 THENSET grade_level = 'B';ELSEIF s_grade >= 60 THENSET grade_level = 'C';ELSESET grade_level = 'Fail';END IF;-- 记录等级日志INSERT INTO logs (message) VALUES (CONCAT('Student ', s_name, ' (ID: ', s_id, ') grade: ', s_grade, ', level: ', grade_level));-- 简单计数SET loop_counter = loop_counter + 1;END IF;UNTIL doneEND REPEAT;CLOSE cur;SET result_message = CONCAT('Graded ', loop_counter, ' students successfully.');ELSESIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid action specified.';END CASE;
END //DELIMITER ;

第三步:测试

-- 加分操作
CALL ProcessStudentGrades('ADD', 10, @msg);
SELECT @msg AS Result;
SELECT * FROM students;
SELECT * FROM logs;-- 减分操作
CALL ProcessStudentGrades('SUBTRACT', 5, @msg);
SELECT @msg AS Result;
SELECT * FROM students;
SELECT * FROM logs;-- 评定等级
CALL ProcessStudentGrades('GRADE', NULL, @msg);
SELECT @msg AS Result;
SELECT * FROM logs;-- 无效操作
CALL ProcessStudentGrades('INVALID', NULL, @msg);
SELECT @msg AS Result;
SELECT * FROM logs;

相关文章:

【MySQL学习】存储过程

目录 一、定义 二、基本语法 1.创建存储过程 2.删除存储过程 3.查看存储过程 三、控制语句 1.变量声明与赋值 四、游标&#xff08;Cursor&#xff09; &#xff08;1&#xff09;声明游标 &#xff08;2&#xff09;处理游标结束 &#xff08;3&#xff09;打开游标 …...

Bp靶场 - Jwt

你知道JWT漏洞如何进行攻击利用吗&#xff1f;快来看一看如何利用JWT漏洞进行攻击利用把&#xff01;https://mp.weixin.qq.com/s/2iBIEGnkiliprsuHyY5Udg...

手机上的APN是什么,该怎么设置

网上说改个APN就可以让网速快几倍&#xff0c;那到底APN是个什么东西&#xff0c;真的能让网速快几倍吗&#xff1f; APN的作用 网络连接基础&#xff1a;APN&#xff08;接入点名称&#xff09;是手机连接移动网络的“桥梁”&#xff0c;负责识别运营商网络类型&#xff08;…...

[bug]langchain agent报错Invalid Format: Missing ‘Action Input:‘ after ‘Action:‘

在学习langchain的agent时候&#xff0c;采用ollama调用本地的deepseek-r1:32b来做一个agent&#xff0c;代码如下&#xff1a; def create_custom_agent():llm ChatOllama(model"deepseek-r1:32b", temperature0.5)memory ConversationBufferWindowMemory(memory…...

blender关联复制与Three.js网格和材质共享验证

blender和three.js小白的学习之路。 最近看到Three.js官网上说&#xff0c;模型合并是一个很好的优化性能的方式&#xff0c;因为渲染2000个物体总要比一次性渲染一个模型要来的慢。很有道理&#xff01; 但此时就不禁思考一个问题&#xff0c;现有的模型进行合并通过blender…...

Spark宽窄依赖与Join优化:协同划分与非协同划分的底层逻辑

在大数据领域&#xff0c;Spark的性能优化始终是开发者关注的焦点。理解宽依赖&#xff08;Wide Dependency&#xff09;和窄依赖&#xff08;Narrow Dependency&#xff09;的底层原理&#xff0c;能够帮助我们从根本上优化Join操作的性能。本文将通过这两个核心概念&#xff…...

每日算法-250416

今天我们来探讨两道可以通过贪心算法解决的 LeetCode 题目。 什么是贪心算法&#xff1f; 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取在当前状态下最好或最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致结果是全局最…...

python爬虫降低IP封禁,python爬虫除了使用代理IP和降低请求频率,还有哪些方法可以应对IP封禁?

文章目录 前言1. 利用 CDN 节点2. 模拟真实用户行为3. 使用 IP 池轮换策略4. 处理 Cookie 和会话信息5. 分布式爬虫 前言 除了使用代理 IP 和降低请求频率&#xff0c;以下这些方法也能应对 IP 封禁&#xff1a; Python 3.13.2安装教程&#xff08;附安装包&#xff09;Python…...

NLP高频面试题(四十五)——PPO 算法在 RLHF 中的原理与实现详解

近端策略优化(Proximal Policy Optimization, PPO)算法是强化学习领域的一种新颖且高效的策略优化方法,在近年大规模语言模型的人类反馈强化学习(Reinforcement Learning with Human Feedback, RLHF)中发挥了关键作用。本文将以学术严谨的风格,详细阐述 PPO 算法的原理及…...

bert项目解析

读取csv def read_file(file_path):data []label []with open(file_path, "r", encoding"utf-8") as file:reader csv.reader(file)next(reader) # 跳过标题行for row in reader:if len(row) < 2:print(f"跳过不完整行: {row}")continue…...

ubuntu20.04 Android14编译环境配置

ubuntu 更新和必要安装 sudo apt update sudo apt install git sudo apt install python2-minimal sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2 sudo upda…...

lombok requires enabled annotation processing

这个错误信息表明你在使用 Lombok 时&#xff0c;编译器无法正常工作&#xff0c;因为 注解处理器&#xff08;Annotation Processing&#xff09; 没有被启用。Lombok 是一个 Java 库&#xff0c;它通过注解处理器在编译时自动生成代码&#xff08;例如 Getter、Setter、NoArg…...

应用系统中的报表开发成本知多少?

应用系统的开发过程中&#xff0c;报表的业务虽然不算太难&#xff0c;但投入的开发成本可不一定小&#xff0c;因为总会有没完没了的报表要去做&#xff0c;成本的投入不容小觑 下面我们就来分析一下报表开发成本的构成&#xff0c;看看它是多是少 报表的开发成本&#xff0c…...

STM32F103ZET6移植FATFS文件系统教程(W25Q32)

一、FATFS核心特性 跨平台支持‌ 支持FAT12/FAT16/FAT32格式&#xff0c;兼容Windows文件系统‌&#xff1b; 采用标准C语言编写&#xff0c;代码量小且支持RTOS‌。 配置灵活性‌ 通过宏定义实现功能裁剪&#xff0c;例如&#xff1a; FF_FS_READONLY&#xff1a;设为1时禁…...

数据泄露防护系统:全面保护企业信息安全的功能解析

随着信息技术的快速发展&#xff0c;数据泄露事件频发&#xff0c;给企业带来了巨大的经济损失和声誉损害。为了有效应对这一挑战&#xff0c;越来越多的企业开始部署专业的数据泄露防护&#xff08;DLP&#xff09;系统。安固软件作为一款领先的数据防泄漏解决方案&#xff0c…...

【野火模型】利用深度神经网络替代 ELMv1 野火参数化:机制、实现与性能评估

目录 一、ELMv1 野火过程表示法&#xff08;BASE-Fire&#xff09;关键机制野火模拟的核心过程 二、采用神经网络模拟野火过程三、总结参考 一、ELMv1 野火过程表示法&#xff08;BASE-Fire&#xff09; ELMv1 中的野火模型&#xff08;称为 BASE-Fire&#xff09;源自 Commun…...

【WPF】 在WebView2使用echart显示数据

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、NuGet安装WebView2二、代码部分1.xaml中引入webview22.编写html3.在WebView2中加载html4.调用js方法为Echarts赋值 总结 前言 为了实现数据的三维效果&…...

java实现二叉树的前序、中序、后序遍历(递归和非递归方式)以及层级遍历

java实现二叉树的前序、中序、后序遍历以及层级遍历 一、二叉树节点定义二、递归方式1.前序遍历2.中序遍历3.后序遍历 三、非递归方式1.前序遍历2.中序遍历3.后序遍历4.层级遍历5.分层打印 四、测试用例 一、二叉树节点定义 class TreeNode {int val;TreeNode left;TreeNode r…...

学习笔记十三—— 理解 Rust 闭包:从语法到 impl Fn vs Box<dyn Fn>

&#x1f9e0; 理解 Rust 闭包&#xff1a;从语法到 impl Fn vs Box &#x1f4da; 目录 闭包是什么&#xff1f;和普通函数有什么不同&#xff1f;闭包的语法长什么样&#xff1f;闭包“捕获变量”是什么意思&#xff1f;闭包和所有权的关系Fn、FnMut、FnOnce 三种闭包类型的…...

Linux虚拟机filezilla总是连不上

刚好有两个虚拟机&#xff0c;测试了一下问题所在 从第一个到第二个需要设置什么 image PNG 68.59KB image PNG 134.39KB ChatGLM 从第一个到第二个需要设置开启ssh服务&#xff0c;具体步骤如下&#xff1a; 输入以下命令来启动SSH服务&#xff1a; bash 复制 sud…...

NO.94十六届蓝桥杯备战|图论基础-单源最短路|常规dijkstra|堆优化dijkstra|bellman-ford|spfa(C++)

在图G中&#xff0c;假设 v i v_{i} vi​和 v j v_{j} vj​为图中的两个顶点&#xff0c;那么 v i v_{i} vi​到 v j v_{j} vj​路径上所经过边的权值之和就称为带权路径⻓度。 由于 v i v_{i} vi​到 v j v_{j} vj​的路径可能有多条&#xff0c;将带权路径⻓度最短的那条路径…...

DISCO:利用大型语言模型提取反事实

DISCO: Distilling Counterfactuals with Large Language Models - ACL Anthologyhttps://aclanthology.org/2023.acl-long.302/ 1. 概述 尽管在自然语言处理(NLP)领域针对各种推理任务取得了巨大进展(Wang 等, 2018, 2019a;Xu 等, 2020),但数据集偏差仍然是构建鲁棒模型…...

若依微服务版启动小程序后端

目录标题 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件 本地启动&#xff0c;dev对应 nacos里的 xxx-xxx-dev配置文件...

C语言 - 深拷贝与浅拷贝详解

深拷贝与浅拷贝详解 在 C 语言编程中&#xff0c;处理指针和动态内存是常见任务。在涉及数据拷贝操作时&#xff0c;我们经常会听到“深拷贝”和“浅拷贝”这两个术语。理解它们之间的区别对于避免程序中的内存错误和数据覆盖问题至关重要。 本文将全面讲解 C 语言中的深拷贝与…...

Serverless集群搭建:Knative

文章目录 Knative搭建1.准备工作安装Kubernetes安装 Istio 2.部署Knative Knative搭建 搭建流程图&#xff1a; 1.准备工作 准备工作 ● 本安装操作中的步骤 bash 适用于 MacOS 或 Linux 环境。对于 Windows&#xff0c;某些命令可能需要调整。 ● 本安装操作假定您具有现有…...

今日行情明日机会——20250416

指数在区间震荡&#xff0c;还需要等突破下跌趋势企稳 2025年4月16日涨停的主要行业方向分析 1. 外贸&#xff08;9家涨停&#xff09; 细分领域&#xff1a;跨境物流、纺织出口、供应链服务。代表个股&#xff1a; 五板&#xff1a;泰慕士&#xff08;纺织服装出口龙头&…...

STM32基础教程——DMA

目录 前言 ​编辑 技术实现 接线图 代码实现 技术要点 DMA时钟 DMA初始化 DMA数据传输设置 数据改变与显示 实验结果 问题记录 前言 DMA(Direct Memory Access)直接存储器存取&#xff0c;用来提供在外设和存储器 之间或者存储器和存储器之间的高速数据传输。无需…...

Node.js 中文件系统模块(`fs`)的详细总结,包括定义、作用、各种写入方式及使用场景

Node.js 中文件系统模块&#xff08;fs&#xff09;的详细总结&#xff0c;包括定义、作用、各种写入方式及使用场景&#xff1a; &#x1f9e9; 一、fs 模块简介 ✅ 定义 fs&#xff08;File System&#xff09;是 Node.js 官方内置模块&#xff0c;用于实现对文件和目录的操…...

MyBatis与MyBatis-Plus:字段自动填充的两种实现方式

目录 1. 使用 MyBatis 拦截器实现字段自动填充 2. 使用 MyBatis-Plus 实现字段自动填充 1. 使用 MyBatis 拦截器实现字段自动填充 实现步骤 创建拦截器 实现 MyBatis 的 Interceptor 接口&#xff0c;通过拦截 MyBatis 执行的 SQL 操作来自动填充公共字段 Intercepts({Signa…...

比特率、码元速率(波特率)的定义、关系及相关计算公式

一、相关定义 &#xff08;一&#xff09;比特率 比特率&#xff08;Bit Rate&#xff09;&#xff1a;单位时间内传输的二进制比特数&#xff0c;是信息传输速率的度量。单位&#xff1a;比特每秒&#xff08;bit/s&#xff0c;bps&#xff09;。公式&#xff1a;比特率 传…...

炫云平台全面支持Blender4.4云渲染

随着世界渲染大赛众多优秀作品被大家关注&#xff0c;Blender作为建模渲染一体化的软件&#xff0c;也是众多3D艺术家最常用的软件之一。云渲染自然是提升创作效率必不可少的工作。这篇文章说一下炫云云渲染平台近期对Blender云渲染支持的情况。 首先&#xff0c;炫云客户端已经…...

Python自学第1天:变量,打印,类型转化

突然想学Python了。经过Deepseek的推荐&#xff0c;下载了一个Python3.12安装。安装过程请自行搜索。 乖乖从最基础的学起来&#xff0c;废话不说了&#xff0c;上链接&#xff0c;呃&#xff0c;打错了&#xff0c;上知识点。 变量的定义 # 定义一个整数类型的变量 age 10#…...

Flutter 从零到一

iOS 调试与开发工具指南 真机调试 Xcode run 在控制台获取 Dart VM service URIVSCode 点击 Cmd Shift P 选择 Debug: Attach to Flutter on Device粘贴 the URI 后点击 Enter 对于iOS开发者来说&#xff0c;使用appuploader这样的iOS开发助手可以简化真机调试的准备工作。…...

ocr-身份证正反面识别

在阿里云官网&#xff0c;申请一个token [阿里官方]身份证OCR文字识别_API专区_云市场-阿里云 (aliyun.com) 观察一下post请求body部分json字符串&#xff0c;我们根据这个创建一个java对象 先默认是人像面 public class IdentityBody {public String image;class configure…...

深入解析Spring Boot核心组件及其关键功能

【版本&#xff1a;spring-boot-2.1.3.RELEASE】 深入Spring Boot核心组件 Spring Boot是一个流行的框架&#xff0c;简化了基于Spring的应用程序的开发和部署。它通过自动配置和“开箱即用”的特性&#xff0c;使得开发者可以快速启动和运行应用程序。在Spring Boot中&#x…...

JVM 调优不再难:AI 工具自动生成内存优化方案

在 Java 应用程序的开发与运行过程中&#xff0c;Java 虚拟机&#xff08;JVM&#xff09;的性能调优一直是一项极具挑战性的任务&#xff0c;尤其是内存优化方面。不合适的 JVM 内存配置可能会导致应用程序出现性能瓶颈&#xff0c;甚至频繁抛出内存溢出异常&#xff0c;影响业…...

分层式设备控制架构、分布式微服务架构及插件化架构

在现代高端装备制造&#xff08;如半导体设备、精密自动化系统&#xff09;中&#xff0c;分层式设备控制架构、分布式微服务架构和插件化架构是提升系统灵活性、实时性和可扩展性的核心技术。以下从设计原理、实现方式及行业应用三个维度展开说明&#xff1a; &#xfffc; 1.…...

上门服务 APP 30 亿营收商业模式在乌干达的技术赋能与实践

不久前&#xff0c;非洲乌干达出现黑人女技师提供上门足疗服务的消息引发关注。据了解&#xff0c;当地一次40分钟的上门按摩服务仅需约40元人民币&#xff0c;价格仅为国内同类服务的十分之一。这一现象折射出全球健康服务行业正在经历的数字化转型浪潮。 国内领先的上门服务平…...

Chemical Review IF=51.4 综述 | 柔性机器人的当下与未来:材料、技术与应用的深度融合

2025.03.31. 新加坡南洋理工大学研究团队在《Chemical Reviews》期刊上发表 “Soft Materials and Devices Enabling Sensorimotor Functions in Soft Robots” 综述型文章。软机器人的传感器运动功能对其与环境交互至关重要&#xff0c;本文全面综述了相关软材料和设备。传感技…...

Python抽象基类

abstractmethod 详解 abstractmethod 是 Python 中 abc 模块&#xff08;Abstract Base Classes&#xff0c;抽象基类&#xff09;提供的一个装饰器&#xff0c;用于定义抽象方法。抽象方法是一种在基类中声明但不实现具体逻辑的方法&#xff0c;强制子类必须实现该方法。以下…...

计算机网络中各种物理量的单位总结

在计算机网络中&#xff0c;数据速率的单位容易混淆&#xff0c;以下是清晰总结&#xff1a; 一、基本单位区分 比特&#xff08;bit&#xff09;与字节&#xff08;Byte&#xff09; 小写 b 表示 比特&#xff08;bit&#xff09;&#xff0c;是数据传输的基本单位。 大写 B…...

PCIE网卡驱动DMA初始化配置

1. DMA 启用的时机 e1000e 驱动在 设备初始化阶段 启用 DMA&#xff0c;具体步骤如下&#xff1a; (1) PCIe 设备初始化 调用路径&#xff1a; e1000_probe() → e1000_sw_init() → e1000_init_hw() → e1000_configure() 关键操作&#xff1a; 启用 PCIe 设备的 DMA 主控模…...

音视频小白系统入门笔记-1

本系列笔记为博主学习李超老师课程的课堂笔记&#xff0c;仅供参阅 课程传送门&#xff1a;音视频小白系统入门课 音视频基础ffmpeg原理 往期课程笔记传送门&#xff1a;音视频小白系统入门笔记-0 课程实践代码仓库&#xff1a;传送门 音频采集 命令行采集 Android端音频…...

技术速递|使用 BrowserStack App Automate 和 Appium UI 测试 .NET MAUI 应用

作者&#xff1a;Sweeky&Gerald 排版&#xff1a;Alan Wang 本文是 Gerald 的博客《开始使用 Appium 测试 .NET MAUI 应用的 UI 》中创建的 .NET MAUI – 使用 Appium 和 NUnit 进行 UI 测试的续篇。 在本篇博客中&#xff0c;我们将了解如何使用 BrowserStack App Automa…...

在多系统环境中实现授权闭环,Tetra Pak 借助CodeMeter打造食品工业的安全自动化体系

一、 行业背景与安全新挑战 在食品加工自动化不断深化的背景下&#xff0c;食品安全、功能安全与知识产权保护的需求日益迫切。Tetra Pak 作为全球领先的食品加工和包装解决方案提供商&#xff0c;业务遍布 160 多个国家&#xff0c;涵盖从配料混合、碳酸化处理到全线自动包装。…...

Nginx+SpringBoot跨域那些事儿(多域名跨域加强版——Nginx配置详解)

嘿,小伙伴们,咱们接着上回书说到,当你的应用需要支持多个域名跨域访问时,Nginx+SpringBoot这对黄金搭档绝对是你的不二之选!今天,咱们就深入聊聊如何在Nginx中配置多个域名跨域,让你的应用更加灵活、强大! 一、跨域问题再科普(多域名跨域场景) 在前后端分离开发中,…...

基于Python的App流量大数据分析与可视化方案

一、引言 App流量数据通常包括用户的访问时间、停留时间、点击行为、页面跳转路径等信息。这些数据分散在不同的服务器日志、数据库或第三方数据平台中&#xff0c;需要通过有效的技术手段进行整合和分析。Python在数据科学领域的广泛应用&#xff0c;得益于其简洁的语法、强大…...

windows下使用nginx + waitress 部署django

架构介绍 linux一般采用nginx uwsgi部署django&#xff0c;在Windows下&#xff0c;可以取代uwsgi的选项包括Waitressa、Daphnea、Hypercoma和Gunicorna(通过WSLa 运行)。windows服务器一般采用nginx waitress 部署django&#xff0c;,他们的关系如下 django是WEB应用…...

openssh离线一键升级脚本分享(含安装包)

查看当前的版本 [rootmyoracle ~]#ssh -V相关安装包下载地址 openssh下载地址&#xff1a;http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssl下载地址&#xff1a;https://www.openssl.org/source/zlib下载地址&#xff1a;http://www.zlib.net/今天演示从7.4升级…...

【专题刷题】双指针(二)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…...