游标
MySQL游标是只读的,不可滚动且不敏感的。
- 只读:您无法通过游标更新基础表中的数据。
- 不可滚动:您只能按SELECT语句确定的顺序获取行。您无法以相反的顺序获取行。此外,您不能跳过行或跳转到结果集中的特定行。
- 未定型:有两种光标:未定型游标和不敏感游标。敏感光标指向实际数据,而不敏感光标使用数据的临时副本。敏感性游标比不敏感游标执行得更快,因为它不必创建临时数据副本。但是,对来自其他连接的数据所做的任何更改都将影响敏感光标正在使用的数据,因此,如果不更新敏感光标正在使用的数据,则更安全。MySQL游标是敏感的。
使用MySQL游标
首先,必须使用以下DECLARE语句声明游标:
DECLARE cursor_name CURSOR FOR SELECT_statement;
游标声明必须在任何变量声明之后。如果在变量声明之前声明游标,MySQL将发出错误。游标必须始终与SELECT语句关联。
接下来,使用OPEN语句打开游标。OPEN语句初始化游标的结果集,因此,必须在从结果集中获取行之前调用OPEN语句。
OPEN cursor_name;
然后,使用FETCH语句检索光标指向的下一行,并将光标移动到结果集中的下一行。
FETCH cursor_name INTO variables list;
之后,可以在获取之前检查是否有可用的行。
最后,调用CLOSE语句以停用游标并释放与其关联的内存,如下所示:
CLOSE cursor_name;
当光标不再使用时,应关闭它。
使用MySQL游标时,还必须声明NOT FOUND处理程序以在光标找不到任何行时处理情况。因为每次调用FETCH语句时,游标都会尝试读取结果集中的下一行。当光标到达结果集的末尾时,它将无法获取数据,并且会引发一个条件处理程序用于处理此情况。
要声明NOT FOUND处理程序,请使用以下语法:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
这 finished是一个变量,表示光标已到达结果集的末尾。请注意,处理程序声明必须出现在存储过程内的变量和游标声明之后。
示例:
首先,声明一些变量,一个用于循环遍历员工电子邮件的游标和一个NOT FOUND处理程序:
DECLARE finished INTEGER DEFAULT 0;
DECLARE email varchar(255) DEFAULT "";
-- declare cursor for employee email
DEClARE email_cursor CURSOR FOR
SELECT email FROM employees;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
接下来,email_cursor 使用以下OPEN语句打开:
OPEN email_cursor;
然后,迭代电子邮件列表,并连接每个电子邮件用分号(;)分隔的所有电子邮件:
get_email: LOOP
FETCH email_cursor INTO v_email;
IF v_finished = 1 THEN
LEAVE get_email;
END IF;
-- build email list
SET email_list = CONCAT(v_email,";",email_list);
END LOOP get_email;
之后,在循环内部,我们使用 v_finished变量来检查列表中是否有电子邮件来终止循环。
最后,使用以下CLOSE语句关闭游标:
CLOSE email_cursor;
build_email_list存储过程如下:
DELIMITER $$
CREATE PROCEDURE build_email_list ( INOUT email_list VARCHAR ( 4000 ) ) BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_email VARCHAR ( 100 ) DEFAULT "";
DECLARE email_cursor CURSOR FOR
SELECT email FROM employees;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1;
OPEN email_cursor;
get_email :LOOP
FETCH email_cursor INTO v_email;
IF v_finished = 1 THEN
LEAVE get_email;
END IF;
SET email_list = CONCAT( v_email, ";", email_list );
END LOOP get_email;
CLOSE email_cursor;
END $$
DELIMITER ;
SET @email_list = "";
CALL build_email_list(@email_list);
SELECT @email_list;
显示存储过程的特征
要显示存储过程的特征,请使用以下 SHOW PROCEDURE STATUS语句:
SHOW PROCEDURE STATUS [LIKE 'pattern' | WHERE expr];
SHOW PROCEDURE STATUS语句是SQL标准的MySQL扩展。此语句为您提供存储过程的特征,包括数据库,存储过程名称,类型,创建者等。
可以使用 LIKE or WHERE子句根据各种条件过滤掉存储过程。
要列出您有权访问的数据库的所有存储过程,请使用以下 SHOW PROCEDURE STATUS语句:
SHOW PROCEDURE STATUS;
如果要在特定数据库中仅显示存储过程,可以使用SHOW PROCEDURE STATUS语句中的WHERE子句 :
SHOW PROCEDURE STATUS WHERE db = 'mysqldemo';
如果要显示具有特定模式的存储过程(例如,其名称包含)product,则可以使用LIKE作为以下命令:
SHOW PROCEDURE STATUS WHERE name LIKE '%product%';
显示存储过程的源代码
要显示特定存储过程的源代码,请使用以下 SHOW CREATE PROCEDURE语句:
SHOW CREATE PROCEDURE stored_procedure_name
可以在SHOW CREATE PROCEDURE关键字后指定存储过程的名称 。例如,要显示GetAllProducts存储过程的代码,请使用以下语句:
SHOW CREATE PROCEDURE GetAllProducts;