MySQL存储过程与存储函数

2023-05-16

1、创建存储过程

存储过程就是一条或者多条 SQL 语句的集合,可以视为批文件。它可以定义批量插入的语句,也可以定义一个接收不同条件的 SQL。
创建存储过程的语句为 “create procedure”,创建存储函数的语句为 “create function”。

调用存储过程的语句为 “CALL”。

调用存储函数的形式就像调用 MySQL 内部函数一样。

DROP TABLE IF EXISTS t_student;
 
CREATE TABLE t_student
(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  age  INT(11) NOT NULL
);
 
INSERT INTO t_student VALUES(NULL,'大宇',22),(NULL,'小宇',20);

在这里插入图片描述
如上述,t_student 表中的数据有两条。如果我们要分别查询出来这两条数据,显然就是根据 ID 来查询。查询出来了第一条数据后,我们可能会去做其它的操作。等过两天,我们要查询另外一条记录的时候,可能又要再写一次这样的查询语句。
存储过程和存储函数应运而生,这样就可以对某些 SQL 语句进行封装,从而实现功能的复用。
定义一个根据 ID 查询学生记录的存储过程:

DROP PROCEDURE IF EXISTS getStuById;
 
DELIMITER //  -- 定义存储过程结束符号为//
CREATE PROCEDURE getStuById(IN stuId INT(11),OUT stuName VARCHAR(255),OUT stuAge INT(11)) -- 定义输入与输出参数
COMMENT 'query students by their id'  -- 提示信息
SQL SECURITY DEFINER  -- DEFINER指明只有定义此SQL的人才能执行,MySQL默认也是这个
BEGIN
   SELECT name ,age INTO stuName , stuAge FROM t_student WHERE id = stuId; -- 分号要加
END // -- 结束符要加
DELIMITER ;  -- 重新定义存储过程结束符为分号

语法:“create procedure sp_name(定义输入输出参数) 【存储特性】begin SQL语句;END”
IN 表示输入参数;OUT 表示输出参数;INOUT 表示既可以输入也可以输出的参数;sp_name 为存储过程的名字。
如果此存储过程没有任何输入、输出,其实就没有什么意义了,但是 sp_name() 的括号不能省略。

查看刚才创建的存储过程。

SHOW PROCEDURE STATUS LIKE 'g%'

在这里插入图片描述
下面是调用储存过程。对于存储过程提供的临时变量而言,MySQL 规定要加上 “@” 开头。

#study 是当前数据库名称
 
CALL study.getStuById(1,@name,@age);
 
SELECT @name AS stuName,@age AS stuAge;

在这里插入图片描述

CALL getStuById(2,@name,@age);
 
SELECT @name AS stuName,@age AS stuAge;

在这里插入图片描述
这样的好处是,如果一段较为复杂的 SQL 语句,我们可能过了几天再去写它,又费时费力。存储过程可以
封装我们写过的 SQL,在下次只需要调用它的时候,直接提供参数并指明查询结果输出到哪些变量中即可。

提示:如果存储过程一次查询出两个记录,将会提示出错。"[Err] 1172 - Result consisted of more than one row"。
所以需要在存储过程的 SQL 后面加上 “limit 1”。从位偏移量为 0 的,即从查询结果的第一条数据开始,查询一条记录。

2、创建存储函数

存储函数与存储过程本质上是一样的,都是封装一系列 SQL 语句,简化调用。
我们自己编写的存储函数可以像 MySQL 函数那样自由的被调用。

DROP FUNCTION IF EXISTS getStuNameById;
 
DELIMITER //
CREATE FUNCTION getStuNameById(stuId INT)  -- 默认是IN,但是不能写上去。stuId视为输入的临时变量
RETURNS VARCHAR(255)   -- 指明返回值类型
RETURN  (SELECT name FROM t_student WHERE id = stuId); //  -- 指明SQL语句,并使用结束标记。注意分号位置
DELIMITER ;

使用存储函数:

SELECT getStuNameById(1);

在这里插入图片描述
提示:在 return 语句后面,有趣的是,分号在 SQL 语句的外面。如果不加分号,查询结果居然查询出两条记录。

从上述存储函数的写法上来看,存储函数有一定的缺点。首先与存储过程一样,只能返回一条结果记录。另外就是存储函数只能指明一列数据作为结果,而存储过程能够指明多列数据作为结果。

3、定义变量

如果希望 MySQL 执行批量插入的操作,那么至少要有一个计数器来计算当前插入的是第几次。
这里的变量是用在存储过程中的 SQL 语句中的,变量的作用范围在 “begin … end” 中。
没有 default 子句,初始值为 NULL。
定义变量的操作:

DECLARE name,address VARCHAR;  -- 发现了吗,SQL中一般都喜欢先定义变量再定义类型,与Java是相反的。
DECLARE age INT DEFAULT 20; -- 指定默认值。若没有DEFAULT子句,初始值为NULL。

为变量赋值:

SET name = 'jay';  -- 为name变量设置值

DECLARE var1,var2,var3 INT;
SET var1 = 10,var2 = 20;  -- 其实为了简化记忆其语法,可以分开来写
-- SET var1 = 10;
-- SET var2 = 20;
SET var3 = var1 + var2;

使用变量实例。如下表,在做了去除主键约束后,我又添加了一条 “id=1” 的数据。现在希望查询出 “id=1” 记录的数量。
在这里插入图片描述

DROP PROCEDURE IF EXISTS contStById;
 
DELIMITER //  -- 定义存储过程结束符号为//
CREATE PROCEDURE contStById(IN sid INT(11),OUT result INT(11)) -- 定义输入变量
BEGIN
    DECLARE sCount INT;
    SELECT COUNT(*) INTO sCount FROM t_student WHERE id = sid;
    SET result = sCount; -- 用变量为输出结果设值
END // -- 结束符要加
DELIMITER ;  -- 重新定义存储过程结束符为分号
 
CALL contStById(1,@result);
SELECT @result;

在这里插入图片描述
显然,在存储过程中的变量,可以直接与输出变量进行相应的计算。本例直接把 “sCount” 这个变量的值赋值到输出中。

4、定义条件与定义处理程序

定义条件 condition:指的是在执行存储过程中的 SQL 语句时,可能出现的问题;
定义处理程序 handler:当遇到了指定问题时应该如何处理,避免存储过程因执行异常而停止。

定义条件和定义处理程序的位置应该在 “begin … end” 之间。

定义条件的语法:“declare condition_name condition for 错误码或错误值;”
错误码可以视为一个错误的引用,比如 404,它代表的就是找不到页面的错误,而它的错误值可能为 Null Pointer Exception。

DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000'; -- 错误值
DECLARE command_not_allowed CONDITION FOR 1148;  -- 错误码

定义处理程序语法:“declare handler_type handler for condition_name sp_statement;”

handler_type 的值有三种,其中 MySQL支持的有两种: continue 是指遇到错误忽略,继续执行下面的 SQL。exit 表示遇到错误退出,默认的策略就是 exit。(undo 表示遇到错误后撤回之前的操作,MySQL 目前还不支持)

condition_name 可以是我们自己定义的条件,也可以是 MySQL 内置的条件,比如 SQL WARNING。sp_statement 指遇到错误的时候,需要执行饿存储过程或存储函数。
在这里插入图片描述

DECLARE CONTINUE HANDLER FOR SQLSATTE '42S02' SET @info = 'NO_SUCH_TABLE'; -- 忽略错误值为42S02的SQL异常
 
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR_OCCUR'; -- 捕获SQL执行异常并输出信息
 
DECLARE no_such_table CONDITION FOR 1146; -- 为错误码为1146的错误定义条件
DECLARE CONTINUE HANDLER FOR no_such_table SET @info = 'no_such_table'; -- 为指定的条件设置处理程序
DROP TABLE IF EXISTS t_student;
 
CREATE TABLE t_student
(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  age  INT(11) NOT NULL
);

在这里插入图片描述
现在通过存储过程,为这张表插入数据。因为 id 属性有主键约束,所以不能插入相同的 id。

DROP PROCEDURE IF EXISTS insertStu;
 
DELIMITER //  -- 定义存储过程结束符号为//
CREATE PROCEDURE insertStu(OUT result INT) -- 指定输出结果
BEGIN
    DECLARE flag INT(11) DEFAULT 0; -- 指定变量为0
    DECLARE primary_key_limit CONDITION FOR SQLSTATE '23000';  -- 主键约束的错误值
    DECLARE CONTINUE HANDLER FOR primary_key_limit SET @info = -1; -- 设计如果出现错误,@info将会被设置为 -1 
    INSERT INTO t_student(id,name,age) VALUES(1,'dayu',22); -- 插入值,设置主键为1
    SET flag = 1; -- 普通变量设值为1
    SET result = flag;  -- 如果下面的SQL执行出现异常,那么就退出,只有上面的SQL生效。将普通变量的值给输出
    INSERT INTO t_student(id,name,age) VALUES(1,'dayu',22); -- 插入值,设置主键为1
    SET flag = 2; -- 如果处理程序是EXIT,那么就不会执行到这一步了
    SET result = flag; -- 将普通变量的值给输出
END // -- 结束符要加
DELIMITER ;  -- 重新定义存储过程结束符为分号

continue 是指遇到错误忽略,继续执行下面的 SQL。因为是 continue 来处理程序,所以遇到错误后将会继续执行。
另外,第二次插入记录,因为违反了主键约束,所以插入失败,但是存储过程仍然继续执行完毕。

CALL insertStu(@result);
SELECT @result,@info; -- @info没有申明就能调用到,可能是是全局变量吧

运行结果:
在这里插入图片描述
再次查看 t_student 表,只插入了一条记录,但是所有的存储过程都执行完毕了。
在这里插入图片描述
现在,重新执行下面的 SQL。先重新建表,再将处理程序的处理策略换位 exit;在执行存储过程中遇到了错误,那么就立即退出。

DROP TABLE IF EXISTS t_student;
 
CREATE TABLE t_student
(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  age  INT(11) NOT NULL
);
 
DROP PROCEDURE IF EXISTS insertStu;
 
DELIMITER //  -- 定义存储过程结束符号为//
CREATE PROCEDURE insertStu(OUT result INT) -- 指定输出结果
BEGIN
    DECLARE flag INT(11) DEFAULT 0; -- 指定变量为0
    DECLARE primary_key_limit CONDITION FOR SQLSTATE '23000';  -- 主键约束的错误值
    DECLARE EXIT HANDLER FOR primary_key_limit SET @info = -1; -- 使用EXIT策略,遇到SQL错误将会结束这次存储过程
                                                               -- 出现SQL错误则直接退出存储过程的执行
    INSERT INTO t_student(id,name,age) VALUES(1,'dayu',22); -- 插入值,设置主键为1
    SET flag = 1; -- 普通变量设值为1
    SET result = flag;  -- 如果下面的SQL执行出现异常,那么就退出,只有上面的SQL生效。将普通变量的值给输出
    INSERT INTO t_student(id,name,age) VALUES(1,'dayu',22); -- 插入值,设置主键为1
    SET flag = 2; -- 如果处理程序是EXIT,那么就不会执行到这一步了
    SET result = flag; -- 将普通变量的值给输出
END // -- 结束符要加
DELIMITER ;  -- 重新定义存储过程结束符为分号
 
CALL insertStu(@result);
SELECT @result,@info; -- @info没有申明就能调用到,可能是是全局变量吧

在这里插入图片描述
@result 的结果为 1,说明执行第二条 SQL 的时候,出现了异常。同样,@info 的值为 -1,也提示处理条件中定义的存储过程被触发。
最后,数据库表中的数据也是:
在这里插入图片描述
如果都是正确的 SQL,会是什么情况呢?

DROP TABLE IF EXISTS t_student;
 
CREATE TABLE t_student
(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  age  INT(11) NOT NULL
);
 
DROP PROCEDURE IF EXISTS insertStu;
 
DELIMITER //  -- 定义存储过程结束符号为//
CREATE PROCEDURE insertStu(OUT result INT) -- 指定输出结果
BEGIN
    DECLARE flag INT(11) DEFAULT 0; -- 指定变量为0
    DECLARE primary_key_limit CONDITION FOR SQLSTATE '23000';  -- 主键约束的错误值
    DECLARE EXIT HANDLER FOR primary_key_limit SET @info = -1; -- 设计如果出现错误,@info将会被设置为 -1 
    INSERT INTO t_student(id,name,age) VALUES(NULL,'dayu',22); -- 
    SET flag = 1; -- 普通变量设值为1
    SET result = flag;  -- 如果下面的SQL执行出现异常,那么就退出,只有上面的SQL生效。将普通变量的值给输出
    INSERT INTO t_student(id,name,age) VALUES(NULL,'dayu',22); -- 
    SET flag = 2; -- 如果处理程序是EXIT,那么就不会执行到这一步了
    SET result = flag; -- 将普通变量的值给输出
END // -- 结束符要加
DELIMITER ;  -- 重新定义存储过程结束符为分号
 
CALL insertStu(@result);
SELECT @result,@info; -- @info没有申明就能调用到,可能是是全局变量吧

在这里插入图片描述
在这里插入图片描述

6、流程控制的使用

(1)if 语句的使用

DROP PROCEDURE IF EXISTS testIf;
DELIMITER //
CREATE PROCEDURE testIf(OUT result VARCHAR(255))
BEGIN
     DECLARE val VARCHAR(255);
     SET val = 'a';
     IF val IS NULL
        THEN SET result = 'IS NULL';
        ELSE SET result = 'IS NOT NULL';
     END IF;
END //
DELIMITER ;
 
CALL testIf(@result);
SELECT @result;

在这里插入图片描述
(2)case 语句

DROP PROCEDURE IF EXISTS testCase;
DELIMITER //
CREATE PROCEDURE testCase(OUT result VARCHAR(255))
BEGIN
     DECLARE val VARCHAR(255);
     SET val = 'a';
     CASE val IS NULL
         WHEN 1 THEN SET result = 'val is true';
         WHEN 0 THEN SET result = 'val is false';
         ELSE SELECT 'else';
     END CASE;
END //
DELIMITER ;
 
CALL testCase(@result);
SELECT @result;

在这里插入图片描述
(3)loop
loop 用于重复执行 SQL。leave 用于退出循环。

DROP PROCEDURE IF EXISTS testLoop;
DELIMITER //
CREATE PROCEDURE testLoop(OUT result VARCHAR(255))
BEGIN
     DECLARE id INT DEFAULT 0;
     add_loop:LOOP
	   SET id = id + 1;
	   IF id>10 THEN LEAVE add_loop; -- 可在此处修改成批量插入
	   END IF;
     SET result = id;
     END LOOP add_loop;
END //
DELIMITER ;
 
CALL testLoop(@result);
SELECT @result;

在这里插入图片描述
下面是一个批量插入的例子:

DROP TABLE IF EXISTS t_student;
 
CREATE TABLE t_student
(
    id INT(11) PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  age  INT(11) NOT NULL
);
 
DROP PROCEDURE IF EXISTS testLoop;
DELIMITER //
CREATE PROCEDURE testLoop(IN columnCount INT(11))
BEGIN
     DECLARE id INT DEFAULT 0;
     add_loop:LOOP
	SET id = id + 1;
	IF id>columnCount THEN LEAVE add_loop;
	END IF;
       INSERT INTO t_student(id,name,age) VALUES(id,'dayu',22);
     END LOOP add_loop;
END //
DELIMITER ;
 
CALL testLoop(15);

在这里插入图片描述
(4)while

DROP PROCEDURE IF EXISTS testWhile;
DELIMITER //
 
CREATE PROCEDURE testWhile(IN myCount INT(11),OUT result INT(11))
BEGIN
   DECLARE i INT DEFAULT 0 ; -- 定义变量
   WHILE i < myCount DO  -- 符合条件就循环
       -- 核心循环SQL;  
       SET i = i + 1 ; -- 计数器+1
   END WHILE;       -- 当不满足条件,结束循环  --分号一定要加!
   SET result = i;  -- 将变量赋值到输出
END //
CALL testWhile(10,@result);
SELECT @result AS 循环次数;

在这里插入图片描述

7、使用 “show status” 查看存储过程或函数的状态

SHOW PROCEDURE STATUS LIKE 'C%';

在这里插入图片描述

SHOW FUNCTION STATUS LIKE 'C%';

在这里插入图片描述
知道了存储过程,如果希望查看具体的存储过程或者存储函数的定义:

SHOW CREATE PROCEDURE study.CountStu;
 
-- Create Procedure 列为核心语句
CREATE DEFINER=`root`@`localhost` PROCEDURE `CountStu`(IN stu_sex CHAR,OUT num INT)
BEGIN 
   SELECT COUNT(*) INTO num FROM t_student WHERE sex = stu_sex;
END

在这里插入图片描述
提示:带上数据库的名字,小心查询不到。

查看存储函数有哪些:

SHOW FUNCTION STATUS LIKE 'C%'

在这里插入图片描述
查看具体的存储函数创建语句:

SHOW CREATE FUNCTION study.countStu2
 
-- Create Function 列的语句
CREATE DEFINER=`root`@`localhost` FUNCTION `countStu2`(stu_sex CHAR) 
RETURNS int(11)
RETURN  (SELECT COUNT(*) FROM t_student WHERE sex = stu_sex)

在这里插入图片描述

8、从 information_schema.Routines 表中查询存储过程与函数

原来,MySQL 中的存储过程与存储函数都存放在 information_schema 数据库下的 Routines 表中。

SELECT * FROM information_schema.ROUTINES WHERE ROUTINE_NAME LIKE 'C%'

在这里插入图片描述
如果什么时候忘记了存储函数或者存储过程的名字,可以查询这张表的数据。然后确定了是某个存储过程或者是存储函数,就可以使用 “show create procedure/function 数据库.sp_name” 查看指定的创建语句了。

9、修改存储过程

语法:“alter procedure | function sp_name [存储特性]”

修改存储过程,将读写权限改为 MODIFIES SQL DATE 并指明调用者
ALTER PROCEDURE countStu2
MODIFIES SQL DATE   -- 表示子程序中包含写数据的语句
SQL SECURITY INVOKER  -- 表示调用者才能执行

在这里插入图片描述

存储过程与存储函数的补充

1、存储过程如何修改代码?
虽然提供了 “alter procedure sp_name [存储特性]”,但是只能修改存储过程的存储特性,不能修改 SQL。需要删除并重新创建。

2、存储过程中能调用其它存储过程吗?
可以在存储过程中的 SQL 中通过 CALL 调用其它存储过程,但是不能用 drop 删除其它存储过程。

3、存储过程中的 in 参数可能是中文怎么办?
在定义存储过程的时候,加上 “character set gbk”

DELIMITER //
CREATE PROCEDURE getAddressByName(IN u_name VARCHAR(50) character set gbk , OUT address VARCHAR(50))
BEGIN
     SQL;
END//
DELIMITER ;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL存储过程与存储函数 的相关文章

  • cisco配置交换机管理地址和默认网关

    配置交换机远程管理地址和默认网关 拓扑图如下 xff1a 1 配置PC0 2 配置SW1交换机 Switch config no ip domain lookup 关闭域名解析 Switch config line exec timeout
  • 兄弟们,请求支援,怎么实现互通,全部都互通的

    转载于 https blog 51cto com 14155986 2337267
  • FIFO算法与LRU算法软考试题

    转载于 https www cnblogs com kungfupanda archive 2009 12 25 1632106 html
  • iOS 网络/本地 图片 按自定义比例缩放 不失真 方法

    我尝试了很多种方法 xff0c 终于 xff0c 设计了一个方法 xff0c 能按自己规定的大小压缩 还没失真 如果以后不好用 我再升级 分享给大家 xff1a 43 CGRect scaleImage UIImage image toSi
  • java 输入输出 函数对象构造

    输入输出 输入字符串 不包括最后的换行符 39 n 39 import java io BufferedReader import java io IOException 输入字符一个char import java io InputStr
  • Python 3 加密简介

    Python 3 的标准库中是没多少用来解决加密的 xff0c 不过却有用于处理哈希的库 在这里我们会对其进行一个简单的介绍 xff0c 但重点会放在两个第三方的软件包 xff1a PyCrypto 和 cryptography 上 xff
  • grep 命令的基本使用

    环境变量 xff1a 定义用户的工作环境某个方面的属性 文本文件的查看命令 xff1a cat 连接 能够将后面跟的多个文件的内容 xff0c 依次显示 cat n 在显示时出现行号 E 显示行结束符 v 显示非打印字符不显示制表符tab
  • innodb Cardinality学习笔记

    github 传送门 链接描述 欢迎过来star呀 背景 1 之前对innodb的Cardinality没概念 xff0c 只知道要高选择性的列上建索引 xff0c 比如用户名而不是性别 xff0c 因为性别区分度不高 xff0c 但是这过
  • K8S组件运行原理详解总结

    一 看图说K8S 先从一张大图来观看一下K8S是如何运作的 xff0c 再具体去细化K8S的概念 组件以及网络模型 从上图 xff0c 我们可以看到K8S组件和逻辑及其复杂 xff0c 但是这并不可怕 xff0c 我们从宏观上先了解K8S是
  • ubuntu中apt-get的常用命令。

    使用以下命令清理系统垃圾 sudo apt get autoclean 清理旧版本的软件缓存 sudo apt get clean 清理所有软件缓存 sudo apt get autoremove 删除系统不再使用的孤立软件 xff1d x
  • Qt之设置QWidget背景色

    简述 QWidget是所有用户界面对象的基类 xff0c 这意味着可以用同样的方法为其它子类控件改变背景颜色 Qt中窗口背景的设置 xff0c 下面介绍三种方法 使用QPalette 使用Style Sheet绘图事件 一般我不用QSS设置
  • 计算机机房英文术语,【数据中心】数据中心常见中英术语及解释

    原标题 xff1a 数据中心 数据中心常见中英术语及解释 一 常见中文术语 1 数据中心 为一个建筑群 建筑物或建筑物中的一个部分 xff0c 主要用于容纳设置计算机房及其支持空间 2 进线间 外部缆线引入和电信业务经营者安装通信设施的空间
  • C#学习之接口

    什么是接口 xff1f 其实 xff0c 接口简单理解就是一种约定 xff0c 使得实现接口的类或结构在形式上保持一致 个人觉得 xff0c 使用接口可以使程序更加清晰和条理化 xff0c 这就是接口的好处 xff0c 但并不是所有的编程语
  • neo1973 audio subsystem

    fhttp wiki openmoko org wiki Neo 1973 audio subsystem using Bluetooth headset with GSM NOTE none of this works with GTA0
  • 程序员面试必备书单

    点击关注异步图书 xff0c 置顶公众号 每天与你分享 IT好书 技术干货 职场知识 Tips 参与文末话题讨论 xff0c 即有机会获得异步图书一本 世上最快乐的事 xff0c 莫过于为理想奋斗 一个满意的工作 xff0c 便是为理想奋斗
  • vnc linux 终端打不开,vnc连接后只能看到终端

    我在windows安装了VNC Viewer xff0c 远程链接ubunt12 04服务器 xff0c 发现远程桌面只有一个终端 xff0c 没有桌面 从网上查了一些资料 xff0c 问题得以解决 xff0c 记录如下 xff1a 修改
  • ubuntu11.04下CUDA4.0的安装与配置

    ubuntu11 04下CUDA4 0的安装与配置 1 xff1a 下载CUDA 4 0 安装官网最新的显卡驱动 xff1a 安装方法可以参考 xff1a Ubuntu11 04下安装Nvidia显卡驱动的方法 然后从NVIDIA网站 xf
  • MySQL中如何定位DDL被阻塞的问题

    在生产环境中 xff0c 执行了一个DDL xff0c 发现很久都没有执行完 xff0c 是不是被阻塞了 xff1f 要怎么解决 xff1f 实际上 xff0c 如何解决DDL阻塞的问题 xff0c 是MySQL中一个共性且高频的问题 下面
  • oracle中的index函数,Oracle中的索引详解(整理)

    一 ROWID的概念 存储了row在数据文件中的具体位置 xff1a 64位 编码的数据 xff0c A Z a z 0 9 43 和 xff0c row在数据块中的存储方式 SELECT ROWID last name FROM hr e
  • KM算法学习笔记

    二分图定义 图的顶点恰好可以分成两个集合 xff0c 同一个集合内的顶点间不允许有边 xff0c 处在不同集合的顶点允许有边相连 问题分类 最大匹配问题 xff1a 匈牙利算法 Hopcroft Karp算法最优权值匹配问题 xff1a K

随机推荐