MySQL 的存储过程和存储函数

本文深入探讨了存储过程和存储函数的概念,详细介绍了它们在数据库中的创建、使用及优势,包括减少网络通信量、提高执行速度和适应性等。通过具体实例展示了MySQL中存储过程的创建、参数设置、流程控制及存储函数的使用。


存储过程

SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。

存储过程是可编程的函数,在数据库中创建并保存,可以由SQL语句和控制结构组成。当想要在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。

存储过程的优点:
(1)减少网络通信量。
调用一个行数不多的存储过程与直接调用SQL 语句的网络通信量可能不会有很大的差别,可是如果存储过程包含上百行SQL 语句,那么其性能绝对比一条一条的调用SQL 语句要高得多。
(2)执行速度更快。
有两个原因:首先,在存储过程创建的时候,数据库已经对其进行了一次解析和优化。其次,存储过程一旦执行,在内存中就会保留一份这个存储过程,这样下次再执行同样的存储过程时,可以从内存中直接调用。
(3)更强的适应性。
由于存储过程对数据库的访问是通过存储过程来进行的,因此数据库开发人员可以在不改动存储过程接口的情况下对数据库进行任何改动,而这些改动不会对应用程序造成影响。
(4) 分布式工作。
应用程序和数据库的编码工作可以分别独立进行,而不会相互压制。

MySQL的存储过程
存储过程是数据库的一个重要的功能,MySQL 5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL 5.0开始支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。

MySQL存储过程的创建

		CREATE PROCEDURE  过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 ...] 过程体
		DELIMITER //
		  CREATE PROCEDURE myproc(OUT s int)
		    BEGIN
		      SELECT COUNT(*) INTO s FROM students;
		    END
		    //
		DELIMITER ;
  1. 分隔符
    MySQL默认以";“为分隔符,如果没有声明分割符,则编译器会把存储过程当成SQL语句进行处理,因此编译过程会报错,所以要事先用“DELIMITER //”声明当前段分隔符,让编译器把两个”//"之间的内容当做存储过程的代码,不会执行这些代码;“DELIMITER ;”的意为把分隔符还原。
  2. 参数
    存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用","分割开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT: IN 表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出的参数.
  3. 过程体
    过程体的开始与结束使用BEGIN与END进行标识。

例子

创建一个存储过程:

		DROP PROCEDURE IF EXISTS getStuById;
		DELIMITER //  -- 定义存储过程结束符号为//
		CREATE PROCEDURE getStuById(INOUT userId INT(11),OUT username VARCHAR(255)) -- 定义输入与输出参数
		BEGIN
		   SELECT id,name INTO userId,username FROM t_user WHERE id = userId;
		END // 
		DELIMITER ;

查看我们创建的存储过程:

		SHOW PROCEDURE STATUS LIKE 'get%'

在这里插入图片描述调用一个存储过程:

		set @id=1; //只有INOUT类型才需要先设置一个变量
		CALL test.getStuById(@id,@name);
		SELECT @id AS userId,@name AS username;

在这里插入图片描述

其他操作

定义变量

		DECLARE name,address VARCHAR; //定义两个varchar类型变量
		DECLARE age INT DEFAULT 18;//定义一个默认值为18的整型变量age
		SET name = 'moke';  //为name变量设置值

流程控制

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


存储函数

存储函数与存储过程本质上是一样的,都是封装一系列SQL语句,简化调用。
创建一个存储函数:

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

查看创建的存储函数:

		SHOW FUNCTION STATUS

在这里插入图片描述调用存储函数:

		SELECT getStuNameById(2);

在这里插入图片描述
与存储过程的区别:
更改存储函数的 SQL 语句为:

		RETURN  (SELECT id,name FROM t_user WHERE id = userId);

此时我们再次调用getStuNameById存储函数会报错:
在这里插入图片描述
存储函数只能指明一列数据作为结果,而存储过程能够指明多列数据作为结果

好的,以下是一个简单的 MySQL 存储过程存储函数的实验。 首先,创建一个测试表 test_table,包含两个字段 id name: ```sql CREATE TABLE test_table ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL, PRIMARY KEY (id) ); ``` 接着,我们创建一个存储过程,用于向 test_table 中插入数据: ```sql DELIMITER // CREATE PROCEDURE insert_data() BEGIN DECLARE i INT DEFAULT 1; WHILE (i <= 10) DO INSERT INTO test_table (name) VALUES (CONCAT('Name ', i)); SET i = i + 1; END WHILE; END // DELIMITER ; ``` 该存储过程名为 insert_data,它使用了一个 WHILE 循环来向 test_table 中插入 10 条数据,每个数据的 name 字段都是 'Name ' 加上当前循环次数 i。 接下来,我们创建一个存储函数,用于统计 test_table 中数据的数量: ```sql DELIMITER // CREATE FUNCTION count_data() RETURNS INT BEGIN DECLARE count INT; SELECT COUNT(*) INTO count FROM test_table; RETURN count; END // DELIMITER ; ``` 该存储函数名为 count_data,它使用了一个 SELECT COUNT(*) 查询来统计 test_table 中数据的数量,并将结果赋值给 count 变量,最终返回 count。 现在,我们可以分别调用 insert_data 存储过程 count_data 存储函数来测试它们的效果: ```sql CALL insert_data(); SELECT count_data(); ``` 执行后,我们可以看到 test_table 中已经插入了 10 条数据,同时 count_data 函数返回的结果也是 10。 这就是一个简单的 MySQL 存储过程存储函数的实验。当然,实际使用中还有很多更复杂的情况需要考虑处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值