MySQL基础系列之 存储过程和函数

版权声明:如需转载,请注明出处。 https://blog.csdn.net/caiqing116/article/details/84843908

摘要:存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合
存储过程无返回值,函数有返回值
存储过程的参数可以使用IN、OUT、INOUT,函数只能使用IN
创建存储过程 CREATE PROCEDURE
创建函数使用 CREATE FUNCTION
使用CALL语句来调用存储过程

1、存储过程
(1.1)创建语句
CREATE PROCEDURE sp_name([ proc_parameter ]) [characteristics] routine_body
(1.2)参数说明
sp_name:存储过程名称
proc_parameter: IN | OUT | INOUT param_name type
IN:输入参数
OUT:输出参数
INOUT:既可以输入也可以输出
param_name 参数名称
type 参数类型

characteristics:存储过程的特性
LANGUAGE SQL
说明routine_body部分是由sql语句组成当前系统支持的语言
[NOT] DETERMINISTIC
指明存储过程执行的结果是否正确即相同的输入得到的结果是否相同
DETERMINISTIC
相同的输入得到的结果相同
NOT DETERMINISTIC
相同的输入得到的结果不相同
CONTAINS SQL | NO SQL | READS SQL DATA | MODEIFIES SQL DATA
指明子程序使用SQL语句的限制
CONTAINS SQL
包含sql语句但不包含读写数据的语句
NO SQL
子程序不包含sql语句
READS SQL DATA
包含读数据语句
MODIFIES SQL DATA
包含写数据语句
SQL SECURITY{DEFINER}{INVOKER}
指明谁有权限来执行
DEFINER
表示只有定义者才能执行(默认)
INVOKER
表示拥有权限者可以执行
COMMENT ‘String’
注释信息 可以用来描述存储过程或函数

routine_body
是sql代码内容 可以用BEGIN…END来表示sql语句的开始和结束

DELIMITER //
作用:将mysql结束符设为// 可以避免与 存储过程中的sql语句结束符冲突
存储过程定义完之后使用 DELIMITER ; 恢复默认结束符

(1.3)创建存储过程实例

DELIMITER//
CREATE PROCEDURE avgFruitPrice2(OUT avgprice DOUBLE)
BEGIN
    SELECT AVG(price) INTO avgprice
    FROM tb_proceduretest;
END//
DELIMITER;

(1.4)调用储存过程
CALL avgFruitPrice2(@avgprice);
(1.5)查看输出变量值
SELECT @avgprice;

2、创建存储函数
(2.1)创建语句
CREATE FUNCTION func_name( func_parameter )
RETURNS type
[characteristic…] routine_body

func_name 存储函数名称
func_parameter 存储过程的参数列表
RETURNS type 表示函数返回数据类型
(2.2)创建函数例子

CREATE FUNCTION nameByZip()
    RETURNS CHAR(50)
RETURN (SELECT s_name FROM tb_supplies WHERE s_call='45678' );
例子:
DELIMITER//
BEGIN
    CREATE FUNCTION returnAvgprice()
    RETURNS VARCHAR(50)
    RETURN(SELECT AVG(price) FROM tb_proceduretest);
END//
DELIMITER;

(2.3)调用存储函数
SELECT returnAvgprice();

如果存储函数中的RETURN语句返回一个类型不同于函数RETURNS字句中指定类型的值,返回值将被强制为恰当的类型
指定参数IN OUT INOUT 只对PROCEDURE是合法的(FUNCTION 总是默认为 IN)RETURNS 字句只能对FUNCTION 做指定 用来指定函数的返回类型
函数体必须包含一个RETURN value语句

3、变量的使用
(1)定义变量DECLARE
DECLARE var_name[,varname] data_type [DEFAULT value]
var_name局部变量的名称
DEFAULT value字句给变量提供一个默认的值 常数或表达式 没有初始值为null
定义名称为myParam变量 类型为INT 默认值100
DECLARE myParam INT DEFAULT 100;

4、为变量赋值
SET var_name = expr[,var_name = expr]…;
声明3个变量 var1 var2 var3 数据类型为INT 使用SET为变量赋值
DECLARE var1 var2 var3 INT;
SET var1=10,var2=20;
SET var3=var1+var2;

SELECT … INTO 为一个或多个变量赋值
SELECT col_name[,…] INTO var_name[,…] table_expr;
#table_expr 表示查询条件表达式

DECLARE fruitname CHAR(50);
DECLARE fruitprice DECIMAL(8,2);
SELECT f_name,f_price INTO fruitname,fruitprice
FROM tb_fruits
WHERE f_id=‘1’;

5、定义条件和处理程序
定义条件

DECLARE condition_name CONDITION FOR [condition_type]
[condition_type]:
SQLSTATE[VALUE] sqlstate_value|mysql_error_code

condition_name参数条件名称
condition_type条件类型
sqlstate_value长度5的字符串类型错误代码
mysql_error_code为数字类型错误代码
ERROR 1142(42000) sqlstate_value:42000 mysql_error_code:1142

DECLARE commond_not_allowed CONDITION FOR SQLSTATE ‘42000’;
DECLARE commond_not_allowed CONDITION FOR 1148;

定义处理程序
DECLARE handler_type HANDLER FOR condition_value[,…] sp_statement
handler_type:错误处理方式CONTINUE|EXIT|UNDO
CONTINUE 遇到错误不处理继续执行
EXIT 遇到错误马上退出
UNDO 遇到错误撤回之前的操作

condition_value: SQLSTATE[VALUE] sqlstate_value
SQLSTATE[VALUE] sqlstate_value包5个字符的字符串错误值
condition_name 表示DECLARE CONDITION定义的错误条件名称
SQLWARNING 匹配所有以01开头的SQLSTATE错误代码
NOT FOUND 匹配所有以02开头的SQLSTATE错误代码
SQLEXCEPTION 匹配所有没有被SQLWARING或NOT FOUND捕获的SQLSTATE错误
mysql_error_code 匹配数值类型错误代码

sp_statement 为程序语句段,表示在遇到错误定义是,需要执行的存储过程或函数

定义处理程序的几种方式
#方法1:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE ‘42S02’ SET @info=‘NO_SUCH_TABLE’;
#方法2:捕获mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info=‘NO_SUCH_TABLE’;
#方法3:先定义条件,然后调用
DECLARE no_such_table CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR no_such_table SET @info=‘NO_SUCH_TABLE’;
#方法4:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info=‘ERROR’;
#方法5:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info=‘NO_SUCH_TABLE’;
#方法6:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info=‘NO_SUCH_TABLE’;

#定义条件和处理程序执行过程

CREATE TABLE tb_procedure(
    id INT PRIMARY KEY
);

DELIMITER //
CREATE PROCEDURE handlerDemo()
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1;
    SET @x=1;
    INSERT INTO tb_procedure VALUES(1);
    SET @x=2;
    INSERT INTO tb_procedure VALUES(1);
    SET @x=3;
END//

CREATE PROCEDURE handlerDemo()
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1;
    SET @x=1;
    INSERT INTO tb_test2(username,password) VALUES('c','123');
    SET @x=2;
    INSERT INTO tb_test2(username,password) VALUES('q','234');
    SET @x=3;
END//

DELIMITER ;

#调用存储过程
CALL handlerDemo(); 结果:Query OK,0row affected 1 warning(0.00 sec)
#查看调用过程结果
SELECT @x; 结果:@x=3;

猜你喜欢

转载自blog.csdn.net/caiqing116/article/details/84843908