MySQL高阶之存储过程

news2024/11/15 10:44:39

什么是存储过程?

存储过程可称为过程化SQL语言,是在普通SQL语句的基础上增加了编程语言的特点,把数据操作语句(DML)和查询语句(DQL)组织在过程化代码中,通过逻辑判断、循环等操作实现复杂计算的程序语言。

换句话说,存储过程其实就是数据库内置的一种编程语言,这种编程语言也有自己的变量、if语句、循环语句等。在一个存储过程中可以将多条SQL语句以逻辑代码的方式将其串联起来,执行这个存储过程就是将这些SQL语句按照一定的逻辑去执行,所以一个存储过程也可以看做是一组为了完成特定功能的SQL语句集。每一个存储过程都是一个数据库对象,就像table和view一样,存储在数据库当中,一次编译永久有效。并且每一个存储过程都有自己的名字。客户端程序(Java程序)通过存储过程的名字来调用存储过程。

在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升。

储存过程的优点和缺点:

优点:速度快

缺点:不可移植,例如需要换orcle数据库,不能轻易切换需要重新根据orcle数据库的语法再写一遍,所以不推荐在开发中使用(如果实在不能提升效率可以考虑)并且编写难度大,维护性也差

第一个存储过程

创建存储过程确实通常会使用 BEGIN 和 END 关键字来定义存储过程中的SQL语句块。这些关键字有助于明确指示存储过程中语句的开始和结束位置,特别是在包含多条语句或复杂逻辑时

示例:

从 emp 表中查询 empno 和 ename 两个字段。过程使用了 begin 和 end 关键字来明确定义 SQL 语句的起止。这里是存储过程的具体代码:

create procedure p1()
begin
    select empno, ename from emp;
end;

这个存储过程没有定义输入参数,当调用 call p1(); 时,它会执行这个 select 查询并返回 emp 表中所有行的 empno 和 ename 字段。

删除存储过程

drop procedure if exists p1;

delimiter的解释

其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了。 
默认情况下,delimiter是分号;。

delimiter //; #表示遇到俩个斜杠再执行,修改sql语句的结束符(在命令行中使用)

存储过程的查看

1. 查看创建存储过程的语句:

show create procedure p1;

2. 可以通过系统表 information_schema.routines查看存储过程的状态信息

在MySQL中,只要创建一个存储过程对象,在information_schema.routines 系统表当中就会增加一条记录,这条记录是专门描述存储过程对象状态的。

information_schema.routines 系统表当中存储的不仅仅是存储过程的状态信息,也包括函数对象,触发器对象等等状态信息

语句:

查看系统表当中所有的表:

desc information_schema.routines

指定查看某个表

SELECT *FROM information_schema.routines
WHERE routine_name = 'p1';

这里的关键字段解释如下:

  • SPECIFIC_NAME:存储过程的具体名称,可以用于唯一标识过程(含参数)。
  • ROUTINE_NAME:存储过程的名称(简称,不含参数)。
  • ROUTINE_TYPE:例程的类型,这里是 "PROCEDURE",表示这是一个存储过程,不是函数。
  • ROUTINE_SCHEMA:存储过程所在的数据库名。
  • DATA_TYPE:如果是函数,会显示返回数据的类型;存储过程这一栏通常为空。
  • CREATED:创建存储过程的日期和时间。
  • LAST_ALTERED:最后修改存储过程的日期和时间。
  • ROUTINE_DEFINITION:存储过程的定义,即具体的 SQL 代码。

如何使用这些信息

  • 查询存储过程的详情:你可以通过类似的查询来了解数据库中所有存储过程的详细信息,帮助你理解和管理这些存储过程。
  • 维护和更新存储过程:了解存储过程的最后修改时间和定义可以帮助你维护和更新这些存储过程。

变量

系统变量:

1. 系统变量的分类

  • 全局变量(Global Variables):影响整个MySQL服务器,适用于所有的会话。全局变量的修改可能需要管理员权限,并且可以通过 SET GLOBAL 语句进行更改。全局变量在服务器启动时从配置文件加载,并且大部分全局变量可以动态修改,但有些需要重启服务器才能生效。

  • 会话变量(Session Variables):每个客户端会话都有自己的会话变量副本,改变一个会话变量只会影响当前会话。可以通过 SET SESSION 语句更改会话变量,会话结束后变量会恢复默认值。

2. 查看系统变量

  • 查看所有全局变量:
    SHOW GLOBAL VARIABLES;
  • 查看所有会话变量:
    SHOW SESSION VARIABLES;
  • 查看特定变量:
    SHOW GLOBAL VARIABLES LIKE 'variable_name';
    SHOW SESSION VARIABLES LIKE 'variable_name';
    

使用 LIKE 进行模糊查询

如果你大致知道变量的名称,但不确定具体名称,可以使用 LIKE 关键字进行查询。例如:

  • SHOW VARIABLES LIKE '%char%';:查找包含“char”的所有系统变量。
  • SHOW VARIABLES LIKE '%commit%';:查找包含“commit”的所有系统变量。

3. 设置系统变量

  • 设置全局变量:使用 SET GLOBAL,通常需要管理员权限。修改后,其他新会话将使用修改后的变量值,现有会话不会受影响。
    SET GLOBAL max_connections = 200;
  • 设置会话变量:使用 SET SESSION,仅影响当前会话。
    SET SESSION sql_mode = 'STRICT_ALL_TABLES';
    
    # 设置事务为手动提交
    select @@autocommit; #这个是自动提交
    select @@autocommit = 0; #这个是手动提交

    如果只使用 SET 而不指定 GLOBALSESSION 关键字,默认情况下修改的是会话变量。

持久性

  • 动态变量修改的持久性:通过SET GLOBAL修改的变量在服务器关闭后会失效,重新启动服务器时会从配置文件加载原始值。因此,若要使某些设置永久生效,必须修改MySQL配置文件。
  • 会话变量的持久性:会话变量在每次会话开始时初始化为全局变量的值,修改会话变量不会影响其他会话或持久化。

用户变量

1. 用户变量的定义

  • 用户变量以 @ 符号开头,可以通过 SETSELECT INTO 来赋值。
  • 变量名是大小写不敏感的,并且可以是字母、数字或下划线的组合。

2. 用户变量的赋值方法

1) 使用 SET 语句

使用 SET 语句直接给用户变量赋值。用户变量可以存储任何数据类型,MySQL会自动根据赋值内容确定类型。

SET @var_name = value;
#设置变量值,给变量赋值
select @email = '2367889@qq.com'; #不推荐,因为在sql中,等号有判断是否相等的作用
select @email := '2367889@qq.com';

2) 使用 SELECT INTO 语句

通过 SELECT 查询结果给用户变量赋值。常用于查询单个值并保存到变量中。

SELECT column_name INTO @var_name FROM table_name WHERE condition;
# 将查询结果赋给变量
select money into @m from account where name = '张三';
#mysq1中变量不需要声明。直接赋值就行。如果没有声明变量,直接读取该变量,返回nu11
select @m;

3) 使用 := 赋值符号(推荐使用)

在表达式中使用 := 为用户变量赋值。这种方式经常出现在查询语句中。

SET @var_name := value;

用户变量的作用范围

  • 会话范围:用户变量的作用范围仅限于当前会话(连接)。一旦会话结束,用户变量也随之销毁。
  • 跨查询使用:用户变量可以在同一会话的多个查询中使用,起到临时存储数据的作用。

 注意事项

  • 未定义的用户变量:在使用一个未初始化的用户变量时,MySQL不会报错,而是自动将其值设为 NULL

    SELECT @undefined_var; -- 结果为 NULL
  • 赋值后的值变化:一旦用户变量被赋值后,可以在整个会话中反复使用。会话结束后变量自动消失。

  • 性能问题:用户变量存储在内存中,如果使用太多可能会导致内存占用过多,因此在复杂应用中应谨慎使用。

 局部变量:

1. 局部变量的定义

局部变量必须在存储过程、函数或触发器的声明部分显式声明,使用 DECLARE 关键字进行定义。

DECLARE var_name datatype [DEFAULT value];
  • var_name:变量名。
  • datatype:变量的数据类型,必须是MySQL支持的数据类型,例如 INTVARCHARDECIMAL 等。
  • DEFAULT value:可选,变量的默认值。如果不指定默认值,变量的初始值为 NULL

注意:declare通常出现在begin end之间的开始部分 

与用户变量的差别:

定义方式@var_nameDECLARE var_name
作用范围当前会话存储过程、函数或触发器的执行体内
初始化不需要显式初始化,未赋值前为 NULL必须声明和初始化
使用场景在普通SQL查询中使用,跨查询只能在存储过程、函数或触发器中使用

CREATE PROCEDURE p3()
BEGIN
    /* 声明局部变量 */
    DECLARE num INT DEFAULT 0;
    DECLARE mone INT DEFAULT 0;

    /* 给局部变量赋值 */
    SELECT COUNT(*) INTO num FROM account;  -- 统计 account 表中的用户数
    SET mone := 50;  -- 将 mone 设置为 50

    /* 读取局部变量的值 */
    SELECT num, mone;  -- 输出 num 和 mone 的值
END;

# 调用存储过程
call p3();
/*局部变量只在存储过程中有效,这里是无法访问的*/
select num,mone;

MySQL中的语句:

if语句: 

3aa642670afe4d38b685e2d39763cd11.png

判断一个数字是否为正数、负数或零。 

CREATE PROCEDURE check_simple()
BEGIN
    declare num int default 5;
    if num > 0 then
        SELECT 'Positive';
    elseif num < 0 THEN
        SELECT 'Negative';
    else
        SELECT 'Zero';
    end if;
END;

#调用存储过程
call check_simple();

 参数:

参数类型说明

  • IN:输入参数,存储过程调用时传入的值,默认就是 IN
  • OUT:输出参数,存储过程会通过该参数输出结果。
  • INOUT:即输入又输出,调用时传入值,存储过程修改后返回。
drop procedure check_simple2;

CREATE PROCEDURE check_simple2(in num int, out ans varchar(10))
BEGIN
    if num > 0 then
       set ans := 'Positive';
    elseif num < 0 THEN
       set ans := 'Negative';
    else
        set ans := 'Zero';
    end if;
END;
# 不能用局部变量,需要用用户变量
call check_simple2(10,@ans);
select @ans;

case语句:

a0d753d7f56b4b8a9024c9c35988c3e0.png

CREATE PROCEDURE GetMonthName(IN month_num INT, OUT month_name VARCHAR(20))
BEGIN
    CASE month_num
        WHEN 1 THEN SET month_name = 'January';
        WHEN 2 THEN SET month_name = 'February';
        WHEN 3 THEN SET month_name = 'March';
        WHEN 4 THEN SET month_name = 'April';
        WHEN 5 THEN SET month_name = 'May';
        WHEN 6 THEN SET month_name = 'June';
        WHEN 7 THEN SET month_name = 'July';
        WHEN 8 THEN SET month_name = 'August';
        WHEN 9 THEN SET month_name = 'September';
        WHEN 10 THEN SET month_name = 'October';
        WHEN 11 THEN SET month_name = 'November';
        WHEN 12 THEN SET month_name = 'December';
        ELSE SET month_name = 'Invalid Month';
    END CASE;
END;

调用存储过程:

-- 定义输出变量
SET @result = '';

-- 调用存储过程,传入月份编号
CALL GetMonthName(5, @result);

-- 查看返回的结果
SELECT @result;
CREATE PROCEDURE p8(IN month INT, OUT season VARCHAR(20))
BEGIN
    CASE 
        WHEN month BETWEEN 3 AND 5 THEN 
            SET season := '春季';   -- 春季
        WHEN month BETWEEN 6 AND 8 THEN 
            SET season := '夏季';   -- 夏季
        WHEN month BETWEEN 9 AND 11 THEN 
            SET season := '秋季';   -- 秋季
        WHEN month = 12 OR month = 1 OR month = 2 THEN 
            SET season := '冬季';   -- 冬季
        ELSE 
            SET season := '无效的月份';  -- 无效的月份
    END CASE;
END;

-- 调用存储过程
CALL p8(12, @season);  -- 输入月份12
SELECT @season;        -- 输出季节

while循环:

基本语法

WHILE condition DO
    -- 循环执行的语句
END WHILE;
  • condition:这是循环的条件,返回 true 时,循环将继续执行。如果条件返回 false,循环将结束。
  • DO...END WHILE:表示在 DOEND WHILE 之间的代码是循环体,即在每次循环迭代中会执行的内容。

查找1~num中的所有偶数和


# while 循环
drop procedure p5;

create procedure p5(in num int ,out sum int)
begin
    # 初始化sum,否则sum始终为0
    set sum := 0;
    while num > 0 do
        if num % 2 = 0  then
            set sum := sum + num;
        end if;
        set num := num - 1;
        end while;
end;

repeat循环:

REPEAT 循环是 MySQL 中的另一种循环控制结构,与 WHILE 循环类似,用于重复执行一段代码,直到满足指定的条件。不同之处在于,REPEAT 循环会先执行一次代码块,然后检查条件,条件为 true 时退出循环。因此,它至少会执行一次。

基本语法:

REPEAT
    -- 循环执行的语句
UNTIL condition
END REPEAT;
  • UNTIL condition:表示循环何时结束。当 conditiontrue 时,循环终止。
  • REPEAT...UNTIL:表示先执行循环体中的代码,再判断是否满足退出条件。

REPEAT 循环与 WHILE 循环的区别:

  1. REPEAT 循环是先执行后判断,所以即使一开始条件不满足,循环体中的代码也会至少执行一次。
  2. WHILE 循环是先判断条件再执行,如果条件一开始就不满足,循环体中的代码一次也不会执行。

1. 计算从 1 到 n 的数字之和

# repeat循环
drop procedure p6;

create procedure p6(in n int,out sum int)
begin
    set sum := 0;
    repeat
        if n % 2 = 0 then
            set sum := sum + n;
        end if;
        set n := n -1;
        until n <= 0 #注意这里不能添加分号,满足条件就结束循环
        end repeat;
end;

call p6(6,@sumRepeat);
select @sumRepeat;

loop循环:

在 MySQL 中,LOOP 是最基本的循环控制结构之一,它会一直执行循环体中的语句,直到使用 LEAVE 语句退出循环。LOOP 循环通常用于需要手动控制循环终止条件的场景,和 WHILE 以及 REPEAT 循环相比,LOOP 循环不依赖条件,而是必须手动退出。

label_name: LOOP
    -- 循环体的语句
    IF condition THEN
        LEAVE label_name;  -- 当条件满足时,退出循环
    END IF;
END LOOP;
# loop循环 输出1~9,并且不输出5
drop procedure p7;
create procedure p7()
begin
    declare i int default 0;

    myloop : loop
        set i := i + 1;

        # 判断是否为5,iterate相当于continue
        if i = 5 then
            iterate myloop;
        end if;

        if i = 10 then
            leave myloop;
        end if;

        select i;
    end loop;

end;

call p7();

存储过程的游标

在数据库的存储过程中,游标是一个非常有用的工具,它允许程序逐行处理查询结果中的数据。这在需要对查询结果的每一行进行复杂处理或计算时尤其有用。下面是使用游标的一些基本步骤:

1. 声明游标:首先需要声明游标,并定义它将执行的查询。例如,在SQL Server中,可以这样声明一个游标:注意:声明游标需要再声明普通变量之后

DECLARE my_cursor CURSOR FOR
SELECT column1, column2 FROM my_table WHERE condition;
  • DECLARE my_cursor CURSOR FOR:这是声明游标的开始。my_cursor 是游标的名称,你可以用它来引用和操作游标。
  • SELECT column1, column2 FROM my_table WHERE condition;:这部分是一个 SQL 查询语句,它定义了游标将要检索的数据。游标 my_cursor 会访问 my_table 表,并且只选择那些满足 condition 条件的行。在这个查询中,它只会检索 column1 和 column2 这两列的数据。

2. 打开游标:一旦声明了游标,就需要打开它以开始访问行。

 OPEN my_cursor;

3. 获取数据:可以逐行从游标中提取数据。通常,这会涉及到一个循环,每次循环读取一行数据。

FETCH  FROM my_cursor INTO @variable1, @variable2;

这里`@variable1`和`@variable2`是存储从游标中获取的数据的变量。这里把获取的一行的俩列储存在变量中

4. 循环处理数据:一般使用循环(如`WHILE`)来持续从游标中提取数据,并对每行数据进行处理。此处没有处理死循环,将在异常处理改进

drop procedure  if exists test;

create procedure test()
begin
    /*   声明变量   */
    declare name varchar(10) default null;
    declare money int default 0;
    declare done boolean default true;
    /*   声明游标   */
    declare test_cursor cursor for select account.name,account.money from account;
    /*   打开游标   */
    open test_cursor;
    /*   使用游标   */
    while true do
        fetch test_cursor into name,money;
        select name,money;
        end while;
    /*   关闭游标   */
    close test_cursor;
end;

call test();

出现问题 

account表中数据如下: 

但是输出:

原因:

当前代码中的 while true do 循环没有判断 fetch 是否成功。因为当游标遍历到结果集的末尾时,fetch 不会成功,也不会自动退出循环,导致程序只输出第一个人后陷入无限循环。 

5. 关闭游标:处理完所有数据后,关闭游标是一个好习惯。

CLOSE my_cursor;

游标虽然在处理逐行数据时非常有用,但通常来说,它们比批量操作或集合操作要慢。因此,除非确实需要对数据进行逐行处理,否则推荐尽量使用更优化的集合操作来提高性能。

存储过程的异常处理

DECLARE {EXIT | CONTINUE} HANDLER FOR condition_value action_statement;

主要组成部分:

  • condition_value:定义处理的条件类型,例如:
    • SQLEXCEPTION:捕获所有 SQL 异常,除了 SQLWARNINGNOT FOUND
    • SQLWARNING:捕获所有 SQL 警告。
    • NOT FOUND:处理未找到数据或游标到达末尾的情况。
    • SQLSTATE 'value':指定具体的 SQLSTATE 错误码。
  • action_statement:当条件触发时执行的操作,例如:CLOSE cursor_name
drop procedure  if exists test;

create procedure test()
begin
    /*   声明变量   */
    declare name varchar(10) default null;
    declare money int default 0;
    declare done boolean default true;
    /*   声明游标   */
    declare test_cursor cursor for select account.name,account.money from account;
    /* 声明退出处理 */
    declare exit handler for not found set done = 1;
    /*   打开游标   */
    open test_cursor;
    /*   使用游标   */
    while done do
        fetch test_cursor into name,money;
        select name,money;
        end while;
    /*   关闭游标   */
    close test_cursor;
end;

call test();

存储函数

1. 存储函数:

   存储函数是带有返回值的存储过程它的参数只允许是 `IN`(输入参数)但是IN不能显示声明,没有 `OUT` 或 `INOUT` 参数。语法格式如下:

CREATE FUNCTION function_name (parameter_list) RETURNS data_type [characteristics]
BEGIN
   -- function body
   RETURN ...;
END;

2. 特征:(提高效率)

  • deterministic: 确定性函数。每次传递相同的参数时,返回的结果是固定的。标记为确定性函数可以帮助优化器进行缓存,提高执行效率。

  • no sql: 函数不涉及任何 SQL 语句,即不执行数据库查询操作。该特性告知 MySQL 优化器不需要为该函数考虑查询缓存或其他数据库优化措施。

  • reads sql data: 函数可以执行只读 SQL 查询,告知 MySQL 优化器该函数会访问数据库,但不执行写操作。

    /*
    存储函数
    案例:计算1~n的所有偶数之和
    */
    
    drop function if exists sum_fun;
    
    create function sum_fun(n int) returns int DETERMINISTIC
    begin
        declare result int default 0;
        while n > 0 do
            if n % 2 = 0 then
                set result := result + n;
            end if;
            set n := n - 1;
        end while;
        return result;
    end;
    
    /* 调用存储函数 */
    set @result = sum_fun(100);
    select @result;
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2155583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux常用命令 笔记

Linux常用指令 查看命令ls 列出指定路径下的文件和目录cd 切换目录绝对路径相对路径 pwd 查看当前路径的绝对路径touch 创建空文件cat 显示文件内容echo 显示内容 & 写入文件vim 文本编辑器打开文件编辑文件保存退出 mkdir 创建目录rm 删除文件&目录删除文件删除目录 定…

java重点学习-设计模式

十三 设计模式 工厂模式&#xff1a;spring中使用&#xff08;目的是&#xff1a;解耦&#xff09; 1.简单工厂 所有的产品都共有一个工厂&#xff0c;如果新增产品&#xff0c;则需要修改代码&#xff0c;违反开闭原则是一种编程习惯&#xff0c;可以借鉴这种编程思路 2.工厂方…

分布式锁优化之 防死锁 及 过期时间的原子性保证(优化之设置锁的过期时间)

文章目录 1、AlbumInfoApiController --》testLock()2、AlbumInfoServiceImpl --》testLock()3、问题&#xff1a;可能会释放其他服务器的锁。 在Redis中设置一个名为lock的键&#xff0c;值为111&#xff0c;并且只有在该键不存在时才设置&#xff08;即获取锁&#xff09;。同…

为解决bypy大文件上传报错—获取百度云文件直链并使用Aria2上传文件至服务器

问题描述 一方面组内的服务器的带宽比较小&#xff0c;另一方面使用bypy方式进行大文件(大于15G)上传时会报错&#xff08;虽然有时可以成功上传&#xff0c;但是不稳定&#xff09;&#xff1a; 解决方式 总体思路: 获得云盘需要下载文件的直链复制直链到服务器中使用自带…

Selenium with Python学习笔记整理(网课+网站持续更新)

本篇是根据学习网站和网课结合自己做的学习笔记&#xff0c;后续会一边学习一边补齐和整理笔记 官方学习网站在这获取&#xff1a; https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱的博客文章来进行环境配置,具…

OpenCV运动分析和目标跟踪(3)计算图像序列的加权平均值函数accumulateWeighted()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 更新一个运行平均值。 该函数计算输入图像 src 和累积器 dst 的加权和&#xff0c;使得 dst 成为帧序列的运行平均值&#xff1a; dst ( x , y…

CANopen通讯协议笔记

CANopen通讯协议笔记 CANopen 通信对象编号CANopen整体框架网络管理&#xff08;NMT&#xff09;主要任务上线报文心跳报文过程数据对象&#xff08;PDO&#xff09;SDO服务数据对象对象字典概述 CANopen 通信对象编号 CANopen报文传输采用 CAN 标准帧格式。 这里的CAN-ID也叫…

ARM(Day 2)

一、作业 &#xff08;1&#xff09;汇编代码 .text.globl _start_start:mov r0, #0x5mov r1, #0x10比较r0,r1 是否相等 相等执行stop 不相等执行下一步比较&#xff08; r0 > r1 ?&#xff09;cmp r0, r1 比较实际在做减法 (YES NO )subhi r0, r0, r1 r0 > r1 …

浅谈Spring Cloud:OpenFeign

RestTemplate 方式调用存在的问题&#xff1a; String url "http://userservice/user/" order.getUserId(); User user restTemplate.getForObject(url, User.class); 这是通过URL地址来访问的。但是&#xff1a; 代码可读性差&#xff0c;编程体验不统一参数复…

NCNN 源码(1)-模型加载-数据预处理-模型推理

参考 ncnn 第一个版本的代码。 0 整体流程 demo&#xff1a;squeezenet ncnn 自带的一个经典 demo&#xff1a;squeezenet 的代码: // 网络加载 ncnn::Net squeezenet; squeezenet.load_param("squeezenet_v1.1.param"); squeezenet.load_model("squeezenet_…

对象关系映射ORM

目录 ORM【重要】 1、 什么是ORM 2、 实体类 3、 ORM改造登录案例 ORM【重要】 1、 什么是ORM 目前使用JDBC完成了CRUD,但是现在是进行CRUD,增删改方法要设计很多参数,查询的方法需要设计集合才能返回. 在实际开发中,我们需要将零散的数据封装到对象处理. ORM (Object Rela…

在曲线图上最值和极值点位置进行适当标注

1、首先生成一组0-100的随机数&#xff0c;组内共有100个数据&#xff1b; yyrandi([0,100],[1,100]); 2、求这组数据的功率谱密度&#xff0c;并绘图&#xff1b; msize(yy,2); xdft fft(yy); % 计算功率谱密度 psd (1/m) * abs(xdft).^2; x1:m; loglog(x,psd,Linewid…

恶意windows程序

Lab07-01.exe分析&#xff08;DOS攻击&#xff09; 1.当计算机重启后&#xff0c;这个程序如何确保它继续运行(达到持久化驻留)? 创建Malservice服务实现持久化 先分析sub_401040桉函数 尝试获取名为HGL345互斥量句柄&#xff0c;如果不存在则直接结束流程&#xff1b;如果存…

【设计模式】万字详解:深入掌握五大基础行为模式

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; 【设计模式】&#xf…

主语部分、谓语部分、限定动词 (谓语动词) 和非限定动词 (非谓语动词)

主语部分、谓语部分、限定动词 {谓语动词} 和非限定动词 {非谓语动词} 1. 主语部分 (subject)1.1. Forms of the subject 2. 谓语部分 (predicate)2.1. Cambridge Dictionary2.2. Longman Dictionary of Contemporary English2.3. 谓语部分和谓语动词2.4. Traditional grammar …

240922-Ollama使用Embedding实现RAG

A. 最终效果 B. 文本分块代码 #%% from PyPDF2 import PdfReader from langchain.text_splitter import CharacterTextSplitterpdf_path 2023-LiuGuokai-Meas.pdf pdf_reader PdfReader(pdf_path) text "" for page in pdf_reader.pages:text page.extract_text…

2024年最新 Python 大数据网络爬虫技术基础案例详细教程(更新中)

网络爬虫概述 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;又称为网页蜘蛛&#xff08;Web Spider&#xff09;或网络机器人&#xff08;Web Robot&#xff09;&#xff0c;是一种自动化程序或脚本&#xff0c;用于浏览万维网&#xff08;World Wide Web&#xf…

(学习总结)STM32CubeMX HAL库 学习笔记撰写心得

STM32CubeMX学习笔记撰写心得 引言 在深入学习和实践STM32系列微控制器的开发过程中&#xff0c;我经历了从标准库到HAL库&#xff0c;再到结合STM32CubeMX进行项目开发的转变。这一过程中&#xff0c;我深刻体会到了STM32CubeMX在配置和代码生成方面的强大与便捷。为了检验自…

哈希简单介绍

1.直接定址法&#xff08;值的分布范围集中&#xff09; 比如统计字符串中字符出现的字数&#xff0c;字符范围是集中 2.除留余数法&#xff08;值的分布范围分散&#xff09; hashkey%n 哈希冲突&#xff1a;不同的值映射到相同的位置 解决哈希冲突的方案&#xff1a; 闭散…

抖音短视频矩阵系统OEM源码开发注意事项,功能开发细节流程全揭秘

抖音短视频矩阵系统OEM源码开发注意事项,功能开发细节流程全揭秘 在当今数字化时代背景下&#xff0c;短视频产业正经历前所未有的快速发展。其中&#xff0c;抖音凭借其创新的算法及多元内容生态获得巨大成功&#xff0c;吸引了众多用户。对于意欲进入短视频领域的创业者而言&…