10.1 创建存储过程和函数
MySQL中创建存储过程和函数使用的语句分别是:
CREATE PROCEDURE
和CREATE FUNCTION
。
注意:使用CALL语句来调用存储过程,只能用输出变量返回值。
创建存储过程基本句法:
CREATE PROCEDURE sp_name([proc_parameter]) [characteristics...] routine_body;
CREATE PROCEDURE:用来创建存储函数的关键字;
sp_name:存储过程的名称;
proc_parameter:指定存储过程的参数列表。
(列表形式如下:[IN|OUT|INOUT] param_name type
)
characteristics:指定存储过程的特性。
下面代码演示了存储过程的内容,名称为AvgFruitPrice,返回所有水果的平均价格,输入代码如下:
mysql> CREATE PROCEDURE Proc()
-> BEGIN
-> SELECT * FROM fruits;
-> END //
Query OK, 0 rows affected (0.25 sec)
10.1.2 创建存储函数
基本语法格式:
CREATE FUNCTION func_name([func_parameter]) RETURNS type [characteristics...] routine_body;
例:创建存储函数,名称为NameByZip,该函数返回SELECT语句查询结果,数值类型为字符串型:
mysql> CREATE FUNCTION NameByZip()
-> RETURNS CHAR(50)
-> RETURN (SELECT s_name FROM suppliers WHERE s_call='48075');
-> //
Query OK, 0 rows affected (0.08 sec)
注:DELIMITER ;
将结束符换回来。
10.1.3 变量的使用
变量可以在子程序中声明并使用,这些变量的作用范围是在BEGIN…END程序中。
1.定义变量
句法:DECLARE var_name[,varname]...date_type[DEFAULT value]
2.为变量赋值
句法:SET var_name=expr [,var_name=expr]...;
10.1.4 定义条件和处理程序
1.定义条件
句法:
DECIMAL condition_name CONDITION [condition_type] [condition_type]: SQLSTATE[VALUE] sqlstate_value | mysql_error_code
例:定义“ERROR 1148(42000)”错误,名称为command_not_allowed。可以用两种不同的方法来定义:
//方法一:使用salstate_value
DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000';
//方法二:使用mysql_error_code
DELARE command_not_allow CONDITION FOR 1148
2.定义处理程序
句法:
DELARE handler_type HANDLER FOR condition_value[,...] sp_statement
handler_type:
CONTINUE | EXIT | UNDO
condition_value:
SQLSTATE[VALUE]sqlstate_value
|condition_name
|SQLWARNING
|NOT FOUND
|SQLEXCEPTION
|mysql_error_code
handler_type(错误处理方式):
CONTINUE:遇到错误不处理;
EXIT:遇到错误马上退出;
UNDO:遇到错误后撤回之前的操作,MySQL中暂时不支持这样的操作。
condition_value:表示错误类型。
sp_statement参数为程序语句段,表示在遇到错误时,需要执行的存储过程或函数。
10.1.5 光标的使用
1.声明光标
句法:
DECLARE cursor_name CURSOR FOR select_statement
cursor_name参数表示光标的名称;
select_statement参数表示SELECT语句的内容,返回用于创建光标的结果集。
2.打开光标
句法:OPEN cursor_name{光标名称}
3.关闭光标
句法:CLOSE cursor_name{光标名称}
10.1.6 流程控制的使用
IF val IS NULL
THEN SELECT 'val is NULL';
ELSE SELECT 'val is not NULL';
END IF;
CASE val
WHEN 1 THEN SELECT 'val is 1’;
WHEN 2 THEN SELECT 'val is 2’;
ELSE SELECT 'val is not 1 or 2’;
END CASE
DELARE id INT DEFAULT 0;
add_loop:LOOP
SET id=id+1;
IF id>=10 THEN LEAVE add_loop;
END IF;
END LOOP add_loop;
add_num:LOOP
SET @count=@count+1;
IF @count =50 THEN LEAVE add_num;
END LOOP add_num;
10.2 调用存储过程和函数
10.2.1 调用存储过程
CALL sp_name([parameter[,...]])
10.2.2 调用存储函数
使用SELECT.
10.3查看存储过程和函数
10.3.1 SHOW STATUS语句查看存储过程和函数的状态
SHOW {PROCEDURE|FUNCTION} STATUS [LIKE 'pattern']
代码示例:
SHOW PROCEDURE STATUS LIKE 'C%'\G;
*************************** 1. row ***************************
Db: sys
Name: create_synonym_db
Type: PROCEDURE
Definer: mysql.sys@localhost
Modified: 2018-09-28 18:59:36
Created: 2018-09-28 18:59:36
Security_type: INVOKER
Comment:
Description
Takes a source database name and synonym name, and then creates the
synonym database with views that point to all of the tables within
the source database.
Useful for creating a "ps" synonym for "performance_schema",
or "is" instead of "information_schema", for example.
Parameters
in_db_name (VARCHAR(64)):
The database name that you would like to create a synonym for.
in_synonym (VARCHAR(64)):
The database synonym name.
Example
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql> CALL sys.create_synonym_db('performance_schema', 'ps');
+---------------------------------------+
| summary |
+---------------------------------------+
| Created 74 views in the `ps` database |
+---------------------------------------+
1 row in set (8.57 sec)
Query OK, 0 rows affected (8.57 sec)
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| ps |
| sys |
| test |
+--------------------+
6 rows in set (0.00 sec)
mysql> SHOW FULL TABLES FROM ps;
+------------------------------------------------------+------------+
| Tables_in_ps | Table_type |
+------------------------------------------------------+------------+
| accounts | VIEW |
| cond_instances | VIEW |
| events_stages_current | VIEW |
| events_stages_history | VIEW |
...
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: utf8_general_ci
1 row in set (0.27 sec)
ERROR:
No query specified
10.3.2 SHOW CREATE语句查看存储过程和函数的定义
除了SHOW STATUS之外,MySQL还可以使用SHOW CREATE语句查看存储过程和函数的状态。
SHOW CREATE {PROCEDURE | FUNCTION} sp_name
例:
mysql> SHOW CREATE FUNCTION test.CountPro\G;
10.3.3 从information_schema.Routines表中查看存储过程和函数的信息
语法:
SELECT * FROM information_schema.Rountines WHERE ROUNTINE_NAME='sp_name'
;
10.4 修改存储过程和函数
ALTER {PROCEDURE | FUNCTION} sp_name[characteric...]
10.5 删除存储过程和函数
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
10.6 综合案例
01 创建一个名为sch的数据表,并向表中插入数据
mysql> CREATE TABLE sch(
-> id INT,
-> name VARCHAR(50),
-> glass VARCHAR(50)
-> );
Query OK, 0 rows affected (0.58 sec)
mysql> INSERT INTO sch VALUES(1,'xiaoming','glass1'),
-> (2,'xiaojun','glass2');
Query OK, 2 rows affected (0.11 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> DESC sch;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(50) | YES | | NULL | |
| glass | varchar(50) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.04 sec)
mysql> SELECT * FROM sch;
+------+----------+--------+
| id | name | glass |
+------+----------+--------+
| 1 | xiaoming | glass1 |
| 2 | xiaojun | glass2 |
+------+----------+--------+
2 rows in set (0.00 sec)
02创建一个可以统计表格内记录条数的存储函数,函数名为count_sch
mysql> DELIMITER //
mysql> CREATE FUNCTION count_sch()
-> RETURNS INT
-> RETURN(SELECT COUNT(*) FROM sch);
-> //
Query OK, 0 rows affected (0.10 sec)
mysql> SELECT count_sch()//
+-------------+
| count_sch() |
+-------------+
| 2 |
+-------------+
1 row in set (0.18 sec)
03创建一个存储过程add_id在同时使用前面创建的存储函数返回表sch中的记录数,计算表中所以的id之和
mysql> DELIMITER //
mysql> CREATE PROCEDURE add_id(out count INT)
-> BEGIN
-> DECLARE itmp INT;
-> DECLARE cur_id CURSOR FOR SELECT id FROM sch;
-> DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_id;
-> SELECT count_sch() INTO count;
-> SET @sum=0;
-> OPEN cur_id;
-> REPEAT
-> FETCH cur_id INTO itmp;
-> IF itmp<10
-> THEN SET @sum=@sum+itmp;
-> END IF;
-> UNTIL 0 END REPEAT;
-> CLOSE cur_id;
-> END //
Query OK, 0 rows affected (0.10 sec)
mysql> SELECT @a,@sum //
+------+------+
| @a | @sum |
+------+------+
| NULL | NULL |
+------+------+
1 row in set (0.00 sec)