mysql 开发基础系列17 存储过程和函数(上)
一. 概述
存储过程和函数是事先经过编译并存储在数据库中的一段sql语句集合,可以简化应用开发人员的很多工作,减少数据在数据库与应用服务器之间的传输,提高数据处理效率是有好处的。存储过程和函数的区别在于函数必须有返回值,存储过程的参数可以使用in,out ,inout类型,而函数参数只能是in类型。 创建需要create routine 权限, 修改删除需要alter routine权限,执行需要execute权限。
1.1 创建存储过程,调用,删除
-- 创建 DELIMITER $$ CREATE PROCEDURE proc_city(IN city_id INT ,OUT num INT) READS SQL DATA BEGIN -- 要设置初始值,不然为null 与sqlserver一样 SET num=0; SELECT * FROM city WHERE city.city_id=city_id; SET num=num+1; END $$ DELIMITER ; -- 调用 CALL proc_city (2,@num); SELECT @num;
-- 删除 DROP PROCEDURE proc_city
特征值介绍:
CREATE PROCEDURE proc_name()
{ contains sql | no sql | READS SQL DATA | modifies sql data}
这个特征值只是提供给服务器,并没有根据这些特征值来约束过程实际使用数据的情况。 contains sql 表示子程序不包含读或写数据的语句。no sql表示子程序不包含sql 语句。 READS SQL DATA:表示子程序包含数据的语句,但不包含写数据。modifies sql data 表示子程序包含写数据。默认是contains sql。
1.2 创建函数,调用,删除
-- 创建 SET GLOBAL log_bin_trust_function_creators=TRUE; DELIMITER $$ CREATE FUNCTION fn_city (city_count INT) RETURNS INT BEGIN DECLARE city_count1 INT; -- 要设置初始值, SET city_count1=0; SET city_count1=city_count+1; RETURN city_count1; END $$ DELIMITER ; -- 调用 SELECT fn_city (2);
-- 删除 DROP FUNCTION fn_city
1.3 查看信息
SELECT * FROM information_schema.Routines WHERE ROUTINE_NAME='proc_city' OR ROUTINE_NAME='fn_city'
1.4 变量的使用
DELIMITER $$ CREATE PROCEDURE proc_demo_declare() READS SQL DATA BEGIN -- 定义 DECLARE i INT ; -- 赋值 SET i=10; SELECT i; -- 第二种赋值 SELECT COUNT(1) INTO i FROM city; SELECT i; END $$ DELIMITER ; call proc_demo_declare;
1.5 定义Handler遇到问题的处理步骤
-- 语法 DECLARE {EXIT | CONTINUE} HANDLER FOR {error-number | SQLSTATE error-STRING | CONDITION} SQL statement
(1) 处理类型{EXIT | CONTINUE} continue: 当遇到执行错误时,跳过继续下面的语句。exit: 当遇到执行错误时,停止语句
(2) 触发条件 (SQLSTATE,MYSQL ERROR,CONDITION)MYSQL错误代码。ANSI-standard SQLSTATE code。命名条件。可使用系统内置的SQLEXCEPTION,SQLWARNING和NOT FOUND。
(3)错误触发的操作。
-- 以continue为例 DELIMITER $$ CREATE PROCEDURE proc_demo_handler_continue() BEGIN -- 定义条件 continue : 当遇到执行错误时,跳过继续下面的语句 DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; -- 这条可以插入 INSERT INTO city(country_id,cityname,Citycode) VALUES(2,'中国','cn4'); SET @x=1; -- 这条不能插入,外键约束fk_city_country INSERT INTO city(country_id,cityname,Citycode) VALUES(8,'中国','cn5'); SET @x=2; -- 这条可以插入 INSERT INTO city(country_id,cityname,Citycode) VALUES(2,'中国','cn6'); SET @x=3; END $$ DELIMITER ;
-- 调用 CALL proc_demo_handler_continue; SELECT @x,@x2;
使用了continue: 当遇到执行错误时,跳过继续下面的语句,三条语句,只插入成功二条成功
-- 以exit为例 DELIMITER $$ CREATE PROCEDURE proc_demo_handler_exit() BEGIN -- 定义条件 : 当遇到执行错误时,停止语句 DECLARE EXIT HANDLER FOR SQLSTATE '23000' SET @x2 = 1; -- 这条可以插入 INSERT INTO city(country_id,cityname,Citycode) VALUES(2,'中国','cn4'); SET @x=1; -- 这条不能插入,外键约束fk_city_country INSERT INTO city(country_id,cityname,Citycode) VALUES(8,'中国','cn5'); SET @x=2; -- 这条不可以插入 INSERT INTO city(country_id,cityname,Citycode) VALUES(2,'中国','cn6'); SET @x=3; END $$ DELIMITER ;
-- 调用 CALL proc_demo_handler_exit;SELECT @x,@x2;
使用了exit: 当遇到执行错误时,停止语句, 三条语句,只插入成功第一条