MySQL-存储过程
我們常用的操作數據庫語言SQL語句在執行的時候需要要先編譯, 然后執行; 而存儲過程(Stored Procedure)是一組為了完成特定功能的SQL語句集, 經編譯后存儲在數據庫中, 用戶通過指定存儲過程的名字并給定參數(如果該存儲過程帶有參數)來調用執行它。
一個存儲過程是一個可編程的函數, 它在數據庫中創建并保存。它可以有SQL語句和一些特殊的控制結構組成。當希望在不同的應用程序或平臺上執行相同的函數, 或者封裝特定功能時, 存儲過程是非常有用的。數據庫中的存儲過程可以看做是對編程中面向對象方法的模擬。它允許控制數據的訪問方式。可以認為是用來重復執行的一系列SQL語句(類似函數)。
優點: 如果一系列SQL語句, 被用來多次執行, 那么用存儲過程是很快的。因為存儲過程是預編譯的。在首次運行一個存儲過程時查詢, 優化器對其進行分析優化, 并且給出最終被存儲在系統表中的執行計劃。而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優化, 速度相對要慢一些。
先講解變量:
MySQL中變量以"@"開始 形式為"@變量名" 使用set、select配合":="、"="來進行設置或賦值 比如"set @name='John'", "set @name:='John'", "select @mid:=max(id) from tname"類似來設置變量 set可以用":=", 也可以用"=", 但select只能用":=" 因為select語句中"="表示相等判斷
系統變量: 服務器運行時許多變量可以動態更改,而無需重啟服務器,即動態配置。設置用戶變量的時候加上GLOBAL等就是設置系統變量 可以使用"set GLOBAL 變量名"或者"set @@global.變量名"來設置系統變量 系統變量對所有客戶端有效 只有超級權限的用戶才可以設置系統變量 引用的時候只能用@@
用戶變量/會話變量: 基于會話變量實現的,可以暫存值,并傳遞給同一連接里的下一條sql使用的變量。經常用來向SQL中傳值。當客戶端連接退出時,變量會被釋放。設置用戶變量時沒有加上GLOBAL等就是設置會話變量 即使用默認的SESSION(LOCAL) 可以使用"set @變量名"、"set SESSION 變量名"、"set @@session.變量名" 是跟客戶端綁定的 設置的變量只對連接的客戶端有效 客戶端關閉后變量消失
局部變量: 在BEGIN、END語句塊之間設置的變量
局部變量和用戶變量區分在于三點:
1.定義語句不同,用戶變量使用set定義,局部變量使用declare定義;
2.用戶變量是以"@"開頭的,而局部變量沒有這個符號;
3.作用范圍,用戶變量作用于本客戶端,局部變量作用于本塊;
@@var_name如果不指定global|local|session, 則返回session中的值, 否則返回global的值 實用原則: 普通變量用@, 系統變量用@@
總結: 變量包括系統變量、會話變量和局部變量(只要記住有這三種類型變量及其區分就行了), 且變量的只只能為單一值(比如count(*)), 不能為查詢出來的多條記錄
查詢變量的值: "select @name"、"select @@global.GROUP_CONCAT_MAX_LEN"、"select @@GROUP_CONCAT_MAX_LEN"(查詢的session的)
只要不加global 默認都是session
注: BEGIN、END可以認為是函數中的花括號"{"、"}", 以包含函數體或者結構塊;
創建:
CREATE PROCEDURE 存儲過程名(參數列表)
BEGIN
SQL語句(比如 "SELECT * INTO s FROM USERS;");? #語句以分號結束
END
注: 可以用"DELIMITER //"來設置MySQL的語句結束符號 記得改完再改回來
參數類型有三種IN(輸入參數, 在調用存儲過程時指定, 相當于PHP的值傳遞), OUT(輸出參數, 可返回, 相當于PHP的引用傳值, 不論用戶傳值與否初始都為NULL), INOUT(輸入輸出參數)
刪除:
DROP PROCEDURE 存儲過程名
修改:
ALTER PROCEDURE 存儲過程名(參數列表)
語句塊
查詢:
SHOW CREATE PROCEDURE 數據庫名.存儲過程名 //查看存儲過程的詳細
SHOW PROCEDURES STATUS //查看所有或者某個數據庫下的存儲過程 后也可以跟where db='數據庫名' 指定數據庫;
調用:
CALL 存儲過程名(參數列表)
注: CALL語句可以用聲明為OUT或的INOUT參數的參數給它的調用者傳回值 存儲過程名稱后面必須加括號 哪怕該存儲過程沒有參數傳遞
注釋:
1.使用"--" 單行注釋
2.使用"/**/" 多行注釋
?
DECLARE語句用來聲明局部變量, 僅被用在BEGIN, END復合語句里, 且必須在復合語句的開頭, 任何其他語句之前 句式為DECLARE variable_name [,variable_name...] datatype [DEFAULT value];
示例: DECLARE l_int int unsigned default 4000000;(跟創建表結構時一樣)
SELECT INTO語句來對變量進行賦值 select user, pass into x, y from user; 變量名不能與列名相同!!
存儲過程參數:
參數變量以及里面DECLARE的變量都不用@
MySQL 存儲過程參數(in)
MySQL 存儲過程 "in" 參數:跟 C 語言的函數參數的值傳遞類似, MySQL 存儲過程內部可能會修改此參數,但對 in 類型參數的修改,對調用者(caller)來說是不可見的(not visible)
MySQL 存儲過程參數(out)
MySQL 存儲過程 "out" 參數:從存儲過程內部傳值給調用者 在存儲過程內部, 該參數初始賦值為null, 無論調用者調用存儲過程時是否給此參數設置值
MySQL 存儲過程參數(inout)
MySQL 存儲過程 inout 參數跟C語言的引用傳遞類似 可以從存儲過程內部傳值給調用者 不同的是:調用者還可以通過 inout 參數傳遞值給存儲過程
總結: 如果僅僅想把數據傳給 MySQL 存儲過程,那就使用"in" 類型參數;如果僅僅從 MySQL 存儲過程返回值,那就使用"out" 類型參數;如果需要把數據傳給 MySQL 存儲過程,還要經過一些計算后再傳回給我們,此時,要使用"inout" 類型參數
示例:
create procedure my_pro(in n int)
begin
select @name:=User from user where id=n? limit 1;
end;
?
調用:
set @n=1
call my_pro(@n);
?
結構語句:
if vname='John' then
...
else
...
end if;
?
case vname
when 0 then
...
when 1 then
...
else
...
end case;
?
while vname < 6 do
...
end while;
?
字符串類函數:
CHARSET(str) //返回字串字符集
CONCAT (string2 [,... ]) //連接字串
INSTR (string ,substring ) //返回substring首次在string中出現的位置,不存在返回0
LCASE (string2 ) //轉換成小寫
LEFT (string2 ,length ) //從string2中的左邊起取length個字符
LENGTH (string ) //string長度
LOAD_FILE (file_name ) //從文件讀取內容
LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定開始位置
LPAD (string2 ,length ,pad ) //重復用pad加在string開頭,直到字串長度為length
LTRIM (string2 ) //去除前端空格
REPEAT (string2 ,count ) //重復count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str
RPAD (string2 ,length ,pad) //在str后用pad補充,直到長度為length
RTRIM (string2 ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比較兩字串大小,
SUBSTRING (str , position [,length ]) //從str的position開始,取length個字符,
注:mysql中處理字符串時,默認第一個字符下標為1,即參數position必須大于等于1
?
數學類函數:
ABS (number2 ) //絕對值
BIN (decimal_number ) //十進制轉二進制
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //進制轉換
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小數位數
HEX (DecimalNumber ) //轉十六進制
注:HEX()中可傳入字符串,則返回其ASC-11碼,如HEX('DEF')返回4142143
也可以傳入十進制整數,返回其十六進制編碼,如HEX(25)返回19
LEAST (number , number2 [,..]) //求最小值
MOD (numerator ,denominator ) //求余
POWER (number ,power ) //求指數
RAND([seed]) //隨機數
ROUND (number [,decimals ]) //四舍五入,decimals為小數位數]
?
時間類函數:
ADDTIME (date2 ,time_interval ) //將time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //轉換時區
CURRENT_DATE ( ) //當前日期
CURRENT_TIME ( ) //當前時間
CURRENT_TIMESTAMP ( ) //當前時間戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或時間
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式顯示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上減去一個時間
DATEDIFF (date1 ,date2 ) //兩個日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1為星期天
DAYOFYEAR (date ) //一年中的第幾天
EXTRACT (interval_name FROM date ) //從date中提取日期的指定部分
MAKEDATE (year ,day ) //給出年及年中的第幾天,生成日期串
MAKETIME (hour ,minute ,second ) //生成時間串
MONTHNAME (date ) //英文月份名
NOW ( ) //當前時間
SEC_TO_TIME (seconds ) //秒數轉成時間
STR_TO_DATE (string ,format ) //字串轉成時間,以format格式顯示
TIMEDIFF (datetime1 ,datetime2 ) //兩個時間差
TIME_TO_SEC (time ) //時間轉秒數]
WEEK (date_time [,start_of_week ]) //第幾周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第幾天
HOUR(datetime) //小時
?
參考:http://www.blogjava.net/sxyx2008/archive/2009/11/24/303497.html
參考:http://www.jb51.net/article/30825.htm
轉載于:https://www.cnblogs.com/JohnABC/p/3332919.html
總結
以上是生活随笔為你收集整理的MySQL-存储过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 春运时期,购买的火车票能不能在异地上车?
- 下一篇: mysql字段类型