Mysql流程控制语句和存储过程
一、流程控制语句
条件控制语句
1)IF(a,b,c):
a为布尔表达式,b、c为表达式语句,返回a为true时返回b的结果,a为false时返回c的结果。
eg:select id,name,if(gen=1,'男','女') as gen from user;
2)CASE WHEN [condition] THEN [result] END:
语法:
CASE
WHEN [condition1] THEN [result1]
...
WHEN [conditionn] THEN [resultn]
ELSE result(n+1)
END;
3)if else条件语句:
语法:
if search_condition then statement_list
[elseif search_condition then statement_list] ...
[else statement_list]
end if
循环语句
4)while...end while
先检验条件,再执行循环体
while 条件 do
--循环体
end while
5) repeat ... end repeat
先执行一遍循环体,再检验条件
repeat
--循环体
until 循环条件
end repeat
6)loop ·····endloop:
loop循环不需要初始条件,这点和while 循环相似,同时和repeat循环一样不需要结束条件, leave语句的意义是离开循环
LABLES 标号:
标号可以用在begin repeat while 或者loop 语句前,语句标号只能在合法的语句前面使用。可以跳出循环,使运行指令达到复合语句的最后一步。
二、存储过程
2.1简介
存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象
存储过程是为了完成特定功能的sql语句集,经编译创建并保存在数据库中,用户可以通过指定存储过程的名称并给定参数来调用
优点:
存储过程可以封装,并隐藏复杂的商业逻辑
存储过程可以回传值并可以接受参数
存储过程无法使用select指令来执行,因为它是子程序,与查看表、数据表或用户定义函数不同
存储过程可以用在数据校验,强制执行商业逻辑等
确定:
存储过程往往定制化于特定的数据库上,因支持的编程语言不同,当切换到其他厂商的数据库系统时,需要重写原有存储过程
存储过程的性能调校与编写,受限于各种数据库系统
2.2创建存储过程
CREATE [DEFINER={user | current_user}] PROCEDURE sp_name([proc_paramter[,...]]) [characteristic ...] routine_body proc_paramter: [IN | OUT | INOUT] param_name type characteristic: COMMENT 'string' | LANGUAGE SQL | [NOT] DETERMINISTIC | {CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA} | SQL SECURITY {DEFINER | INVOKER} routine_body Valid SQL routine statement [begin_label:] BEGIN [statement_list] ... END [end_label]
2.3参数
MySQL存储过程的参数有以下三种:
IN 输入参数,表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数厄值不被返回
OUT 输出参数:改制在存储过程内部被改变,并可返回
INOUT 输入输出参数:调用时指定,并可以被改变和返回
IN参数例子
OUT参数例子
INOUT参数例子
2.4变量
变量定义:
局部变量的定义一定要放在存储过程体的开始:
DECLARE variable_name [,variable_name2..] datatype [DEFAULT value];
eg: DECLARE p_int int default 4000;
变量赋值:
SET 变量名=表达式[,variable_name=expression...]
用户变量:
用户变量一般以@开头,滥用用户变量将使得sql难以管理
在MySQL客户端使用用户变量:
在存储过程使用用户变量:
三、存储过程示例
3.1 存储过程实现分页查询功能
DROP PROCEDURE IF EXISTS pr_pager; DELIMITER // CREATE PROCEDURE pr_pager( IN p_table_name VARCHAR(128), IN p_fields VARCHAR(1024), IN p_page_size INT, IN p_page_now INT, IN p_order_string VARCHAR(128), IN p_where_string VARCHAR(1024), OUT p_out_rows INT ) BEGIN DECLARE m_begin_row INT DEFAULT 0; DECLARE m_limit_strig CHAR(64); SET m_begin_row = (p_page_now - 1) * p_page_size; SET m_limit_strig = CONCAT(' LIMIT ',m_begin_row,', ',p_page_size); SET @COUNT_STRING = CONCAT('SELECT COUNT(*) INTO @ROWS_TOTAL FROM ',p_table_name,' ',p_where_string); SET @MAIN_STRING = CONCAT('SELECT ',p_fields,' FROM ',p_table_name,' ',p_where_string,' ',p_order_string,m_limit_strig); PREPARE coun_stmt FROM @COUNT_STRING; EXECUTE coun_stmt; DEALLOCATE PREPARE coun_stmt; SET p_out_rows = @ROWS_TOTAL; PREPARE main_stmt FROM @MAIN_STRING; EXECUTE main_stmt; DEALLOCATE PREPARE main_stmt; END; // DELIMITER ;
PREPARE语句准备好一条SQL语句,并分配给这条SQL语句一个名字供之后调用。准备好的SQL语句通过EXECUTE命令执行,通过DEALLOCATE PREPARE命令释放掉。
3.2动态创建表
DROP PROCEDURE IF EXISTS pr_create_tb; DELIMITER // CREATE PROCEDURE pr_create_tb() BEGIN SET @sql_create_table = CONCAT( 'CREATE TABLE IF NOT EXISTS operrecord_', DATE_FORMAT(CURDATE(),'%y%m%d'), '(', '`oper_id` int(10) NOT NULL AUTO_INCREMENT,', '`oper_role` int(11) NOT NULL,', "`oper_desc` varchar(30) NOT NULL DEFAULT '',", 'PRIMARY KEY (`oper_id`)', ') ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8'); PREPARE sql_create_table FROM @sql_create_table; EXECUTE sql_create_table; END; // DELIMITER ;
动态创建表拼接sql时特别要注意引号问题。