MySql 存储过程
-- ---------------------------- -- Procedure structure for `proc_adder` -- ---------------------------- DROP PROCEDURE IF EXISTS `proc_adder`; DELIMITER ;; CREATE PROCEDURE `proc_adder`(IN a int, OUT b int, INOUT c int) BEGIN #Routine body goes here... DECLARE total_sale INT DEFAULT 0; SET total_count = 10; select * from account; END ;; DELIMITER ;
1,DELIMITER ;;
变更分隔符为;; 默认的分隔符为;
为什么我们必须更改分隔符? 因为我们想将存储过程作为整体传递给服务器,而不是让mysql工具一次解释每个语句。 在END关键字之后,使用分隔符;;来指示存储过程的结束。 最后一个命令(DELIMITER;)将分隔符更改回分号(;)
2,参数
IN:参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
OUT:该值可在存储过程内部被改变,并可返回,存储过程在启动时无法访问OUT参数的初始值
INOUT:调用时指定,并且可被改变和返回
3,调用
set @a = 1; set @c = 2 call proc_test(@a,@b,@c); select @b,@c;
4,if语句
if b = 1 THEN select 'b = 1' as title; elseif c = 2 THEN select 'c = 2'; else select 'aaa'; end if;
5,case语句
CASE b when 1 then select 'b=1' as casetile; when 2 then select 'b=2' as casetile; else select 'bbb'; end case;
6,while
DECLARE x INT; DECLARE str VARCHAR(255); #变量的定义要放在最上面,否则出错 SET x = 1; SET str = ''; WHILE x <= 5 DO SET str = CONCAT(str,x,','); SET x = x + 1; END WHILE; SELECT str;
7,REPEAT
REPEAT SET str = CONCAT(str,x,','); SET x = x + 1; UNTIL x > 5 END REPEAT;
8,函数
DELIMITER $$ CREATE FUNCTION CustomerLevel(p_creditLimit double) RETURNS VARCHAR(10) DETERMINISTIC BEGIN DECLARE lvl varchar(10); IF p_creditLimit > 50000 THEN SET lvl = 'PLATINUM'; ELSEIF (p_creditLimit <= 50000 AND p_creditLimit >= 10000) THEN SET lvl = 'GOLD'; ELSEIF p_creditLimit < 10000 THEN SET lvl = 'SILVER'; END IF; RETURN (lvl); END $$ DELIMITER ;
存储过程调用:
DELIMITER $$ CREATE PROCEDURE GetCustomerLevel( IN p_customerNumber INT(11), OUT p_customerLevel varchar(10) ) BEGIN DECLARE creditlim DOUBLE; SELECT creditlimit INTO creditlim FROM customers WHERE customerNumber = p_customerNumber; SELECT CUSTOMERLEVEL(creditlim) INTO p_customerLevel; END $$ DELIMITER ;
#存储函数仅返回单个值。 如果没有包含INTO子句的SELECT语句,则将会收到错误。