一、流程控制语句

条件控制语句

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

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_数据库

5) repeat ... end repeat

先执行一遍循环体,再检验条件

repeat 

--循环体

until 循环条件 

end repeat

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_SQL_02

6)loop ·····endloop:

loop循环不需要初始条件,这点和while 循环相似,同时和repeat循环一样不需要结束条件, leave语句的意义是离开循环

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_MYSQL存储过程 执行动态SQL_03

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参数例子

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_存储过程_04

OUT参数例子

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_MYSQL存储过程 执行动态SQL_05

INOUT参数例子

 

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_SQL_06

2.4变量

变量定义:

局部变量的定义一定要放在存储过程体的开始:

DECLARE variable_name [,variable_name2..] datatype [DEFAULT value];

eg: DECLARE p_int int default 4000;

变量赋值:

SET 变量名=表达式[,variable_name=expression...]

用户变量:

用户变量一般以@开头,滥用用户变量将使得sql难以管理

在MySQL客户端使用用户变量:

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_存储过程_07

在存储过程使用用户变量:

MYSQL存储过程 执行动态SQL mysql执行存储过程语句_sql_08

 

 

 

 

 

三、存储过程示例

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时特别要注意引号问题。