第十章 存储过程和函数

10.1 创建存储过程和函数
MySQL中创建存储过程和函数使用的语句分别是:
CREATE PROCEDURECREATE 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 流程控制的使用

  1. IF语句
    代码示例:
IF val IS NULL
     THEN SELECT 'val is NULL';
     ELSE SELECT 'val is not NULL';
END IF;
  1. CASE语句
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
  1. LOOP语句
    例:
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;
  1. LEAVE语句
    例:
add_num:LOOP
       SET @count=@count+1;
       IF @count =50 THEN LEAVE add_num;
END LOOP add_num;
  1. ITERATE语句
    语句将执行顺序转到语句段开头处。
    ITERATE语句只可以出现在LOOP、REPEATE和WHILE语句内。
  2. REPEAT语句
  3. WHILE语句

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)

猜你喜欢

转载自blog.csdn.net/weixin_43037507/article/details/85108975