一、流程控制語句
條件控制語句
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時特別要注意引號問題。