CREATE FUNCTION sp_name ([func_parameter[,...]]) RETURNS type [characteristic ...] routine_body proc_parameter: [ IN | OUT | INOUT ] param_name type func_parameter: param_name type
type: Any valid MySQL data type
characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string'
routine_body: Valid SQL procedure statement or statements
ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
characteristic: { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string'
SHOW CREATE {PROCEDURE | FUNCTION} sp_name mysql> select * from routines where ROUTINE_NAME = ‘film_in_stock’ \G
变量
1 2 3 4 5 6
DECLARE var_name[,...] type [DEFAULT value] DECLARE last_month_start DATE; SET var_name = expr [, var_name = expr] ... SET last_month_start = DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH); SELECT col_name[,...] INTO var_name[,...] table_expr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
CREATE FUNCTION get_customer_balance(p_customer_id INT, p_effective_date DATETIME) RETURNS DECIMAL(5,2) DETERMINISTIC READS SQL DATA BEGIN … DECLARE v_payments DECIMAL(5,2); #SUM OF PAYMENTS MADE PREVIOUSLY … SELECT IFNULL(SUM(payment.amount),0) INTO v_payments FROM payment WHERE payment.payment_date <= p_effective_date AND payment.customer_id = p_customer_id; … RETURN v_rentfees + v_overfees - v_payments; END $$
条件
条件定义
1 2 3 4 5
DECLARE condition_name CONDITION FOR condition_value
mysql> delimiter $$ mysql> mysql> CREATE PROCEDURE payment_stat () -> BEGIN -> DECLARE i_staff_id int; -> DECLARE d_amount decimal(5,2); -> DECLARE cur_payment cursor for select staff_id,amount from payment; -> DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_payment; -> -> set @x1 = 0; -> set @x2 = 0; -> -> OPEN cur_payment; -> -> REPEAT -> FETCH cur_payment INTO i_staff_id, d_amount; -> if i_staff_id = 2 then -> set @x1 = @x1 + d_amount; -> else -> set @x2 = @x2 + d_amount; -> end if; -> UNTIL 0 END REPEAT; -> -> CLOSE cur_payment; -> -> END; -> $$ Query OK, 0 rows affected (0.00 sec) mysql> delimiter ;
流程控制
1 2 3 4
IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] ... [ELSE statement_list] END IF
1 2 3 4 5 6 7 8 9 10 11
CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] ... [ELSE statement_list] END CASE Or: CASE WHEN search_condition THEN statement_list [WHEN search_condition THEN statement_list] ... [ELSE statement_list] END CASE
1 2 3
[begin_label:] LOOP statement_list END LOOP [end_label]
1 2 3 4 5 6 7 8 9 10 11
mysql> CREATE PROCEDURE actor_insert () -> BEGIN -> set @x = 0; -> ins: LOOP -> set @x = @x + 1; -> IF @x = 100 then -> leave ins; -> END IF; -> INSERT INTO actor(first_name,last_name) VALUES ('Test','201'); -> END LOOP ins; -> END;
mysql> CREATE PROCEDURE actor_insert () -> BEGIN -> set @x = 0; -> ins: LOOP -> set @x = @x + 1; -> IF @x = 10 then -> leave ins; -> ELSEIF mod(@x,2) = 0 then -> ITERATE ins; -> END IF; -> INSERT INTO actor(actor_id,first_name,last_name) VALUES (@x+200,'Test',@x); -> END LOOP ins; -> END; -> $$ Query OK, 0 rows affected (0.00 sec) mysql> call actor_insert(); Query OK, 0 rows affected (0.00 sec) mysql> select actor_id,first_name,last_name from actor where first_name='Test'; +----------+------------+-----------+ | actor_id | first_name | last_name | +----------+------------+-----------+ | 201 | Test | 1 | | 203 | Test | 3 | | 205 | Test | 5 | | 207 | Test | 7 | | 209 | Test | 9 | +----------+------------+-----------+5 rows in set (0.00 sec)
1 2 3 4 5 6 7 8
-> REPEAT -> FETCH cur_payment INTO i_staff_id, d_amount; -> if i_staff_id = 2 then -> set @x1 = @x1 + d_amount; -> else -> set @x2 = @x2 + d_amount; -> end if; -> UNTIL 0 END REPEAT;