好了,廢話不多說,接著開始Mysql剩下部分的小結了 Mysql 之 基礎下 事務 事務:一系列將要發生或正在發生的連續操作,旨在保證數據操作的完整性。在事務開啟之後,所有的操作都會被臨時存儲到事務日誌,事務日誌只有在收到commit命令之後,才會將操作同步到數據表,其他任何情況都會清空事務日誌,例 ...
好了,廢話不多說,接著開始Mysql剩下部分的小結了
Mysql 之 基礎下
事務
事務:一系列將要發生或正在發生的連續操作,旨在保證數據操作的完整性。在事務開啟之後,所有的操作都會被臨時存儲到事務日誌,事務日誌只有在收到commit
命令之後,才會將操作同步到數據表,其他任何情況都會清空事務日誌,例如突然斷開連接、收到rollback
命令等。事務操作主要包括自動事務(預設的,前天是set autocommit = on / 1;),手動事務(前提是set autocommit = off / 0;)。
手動事務基本模型:
- 開啟事務:start transaction;
- 一頓操作:這裡包括常見的表內數據操作,比如update,insert , delete等語句,這裡也可以設置一些返回點,savepoint + 回滾點名稱;
- 回滾事務:rollback to + 回滾點名稱;
- 提交事務:commit;
自動事務基本模型:
- 一頓操作:對,就是一頓操作
事務特性
- 原子性:
Atomic
,表示事務的整個操作是一個整體,是不可分割的,要麼全部成功,要麼全部失敗; - 一致性:
Consistency
,表示事務操作的前後,數據表中的數據處於一致狀態; - 隔離性:
Isolation
,表示不同的事務操作之間是相互隔離的,互不影響; - 持久性:
Durability
,表示事務一旦提交,將不可修改,永久性的改變數據表中的數據。
鎖機制以後會詳細講解
觸發器
觸發器:trigger
,是指事先為某張表綁定一段代碼,當表中的某些內容發生改變(增、刪、改)的時候,系統會自動觸發代碼並執行。
- 新建觸發器: create trigger + 觸發器名稱 + 觸發器時間(before/after) + 事件類型(update/delete/instert) on 表名 for each row begin 一頓操作語句; end ;這裡一頓操作不能隨意,出現數據集最好使用into來查詢
- 查詢觸發器: show triggers [like "_kity%"][regexp 正在表達式];
- 刪除觸發器: drop trigger + 觸發器名稱;
- 修改觸發器: 觸發器不能修改,只能刪除,同視圖一樣。
存儲過程
存儲過程簡稱過程,procedure
,是一種用來處理數據(增刪改)的方式。簡單點,我們也可以將其理解為沒有返回值的函數。
存儲過程好處:
- 有輸入輸出參數,可以聲明變數,有if/else, case,while等控制語句,通過編寫存儲過程,可以實現複雜的邏輯功能;
- 函數的普遍特性:模塊化,封裝,代碼復用;
- 速度快,只有首次執行需經過編譯和優化步驟,後續被調用可以直接執行,省去以上步驟;
可想而知,通過存儲過程可以封裝各種視圖、觸發器、事務等等,因此可以實現各種風騷操作,先介紹下存儲過程的基本語法:
-
-- ---------------------------- -- Procedure structure for `proc_adder` -- ---------------------------- DROP PROCEDURE IF EXISTS `proc_adder`; DELIMITER $ CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_adder`(IN a int, IN b int, OUT sum int) BEGIN #Routine body goes here... DECLARE c int; if a is null then set a = 0; end if; if b is null then set b = 0; end if; set sum = a + b; END $ DELIMITER ;
簡而言之,格式為:CREATE PROCEDURE 過程名([[IN|OUT|INOUT] 參數名 數據類型[,[IN|OUT|INOUT] 參數名 數據類型…]]) [特性 ...] 過程體,其中需要註意:
-
MySQL預設以";"為分隔符,如果沒有聲明分割符,則編譯器會把存儲過程當成SQL語句進行處理,因此編譯過程會報錯,所以要事先用“DELIMITER //”聲明當前段分隔符,讓編譯器把兩個"//"之間的內容當做存儲過程的代碼,不會執行這些代碼;“DELIMITER ;”的意為把分隔符還原。
-
存儲過程根據需要可能會有輸入、輸出、輸入輸出參數,如果有多個參數用","分割開。MySQL存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT: IN參數的值必須在調用存儲過程時指定,在存儲過程中修改該參數的值不能被返回(輸入),為預設值;OUT參數該值可在存儲過程內部被改變,並可返回(輸出);INOUT參數調用時指定,並且可被改變和返回。
-
過程體的開始與結束使用BEGIN與END進行標識。
-
參數也是具有想要的作用域,局部變數的修改並不會對全部變數有任何損失。
-
有上面所說,變數還是有必要簡要介紹下,這裡再copy一張圖,方便理解:
- 這裡列舉下變數的常見封裝函數,可方便即使調用
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為小數位數] 註:返回類型並非均為整數
數值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
字元串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) //小時 LAST_DAY(date) //date的月的最後日期 MICROSECOND(datetime) //微秒 MONTH(datetime) //月 MINUTE(datetime) //分返回符號,正負或0 SQRT(number2) //開平方
日期 -
存儲過程中的變數語法:DECLARE 變數名1[,變數名2...] 數據類型 [預設值], 內部變數在其作用域範圍內享有更高的優先權,當執行到end時,內部變數消失,不再可見了,在存儲
過程外再也找不到這個內部變數,但是可以通過out參數或者將其值指派給會話變數來保存其值。 -
存儲過程中的變數賦值:SET 變數名 = 變數值 [,變數名= 變數值 ...]。
-
全局變數(用戶變數)的設置:用戶變數一般以@開頭,同樣是利用set賦值,比如set @var1 = "12";
-
調用:用call和你過程名以及一個括弧,括弧裡面根據需要,加入參數,參數包括輸入參數、輸出參數、輸入輸出參數。
-
存儲過程式控制制語句:
#條件語句IF-THEN-ELSE DROP PROCEDURE IF EXISTS proc3; DELIMITER // CREATE PROCEDURE proc3(IN parameter int) BEGIN DECLARE var int; SET var=parameter+1; IF var=0 THEN INSERT INTO t VALUES (17); END IF ; IF parameter=0 THEN UPDATE t SET s1=s1+1; ELSE UPDATE t SET s1=s1+2; END IF ; END ; // DELIMITER ; #CASE-WHEN-THEN-ELSE語句 DELIMITER // CREATE PROCEDURE proc4 (IN parameter INT) BEGIN DECLARE var INT; SET var=parameter+1; CASE var WHEN 0 THEN INSERT INTO t VALUES (17); WHEN 1 THEN INSERT INTO t VALUES (18); ELSE INSERT INTO t VALUES (19); END CASE ; END ; // DELIMITER ; DELIMITER // CREATE PROCEDURE proc5() BEGIN DECLARE var INT; SET var=0; WHILE var<6 DO INSERT INTO t VALUES (var); SET var=var+1; END WHILE ; END; // DELIMITER ; DELIMITER // CREATE PROCEDURE proc6 () BEGIN DECLARE v INT; SET v=0; REPEAT INSERT INTO t VALUES(v); SET v=v+1; UNTIL v>=5 END REPEAT; END; // DELIMITER ; DELIMITER // CREATE PROCEDURE proc7 () BEGIN DECLARE v INT; SET v=0; LOOP_LABLE:LOOP INSERT INTO t VALUES(v); SET v=v+1; IF v >=5 THEN LEAVE LOOP_LABLE; END IF; END LOOP; END; // DELIMITER ; #ITERATE DELIMITER // CREATE PROCEDURE proc8() BEGIN DECLARE v INT; SET v=0; LOOP_LABLE:LOOP IF v=3 THEN SET v=v+1; ITERATE LOOP_LABLE; END IF; INSERT INTO t VALUES(v); SET v=v+1; IF v>=5 THEN LEAVE LOOP_LABLE; END IF; END LOOP; END; // DELIMITER ;
存儲過程之流程 -
查看存儲過程:show procedure status + [like 'pattern'];
-
刪除存儲過程:drop procedure + 過程名;
-
游標:游標是一種能從包括多條數據記錄的結果集中每次提取一條記錄的機制。這裡列舉三種游標迴圈進行數據處理的實例。
CREATE PROCEDURE getTotal() BEGIN DECLARE total INT; ##創建接收游標數據的變數 DECLARE sid INT; DECLARE sname VARCHAR(10); #創建總數變數 DECLARE sage INT; #創建結束標誌變數 DECLARE done INT DEFAULT false; #創建游標 DECLARE cur CURSOR FOR SELECT id,name,age from cursor_table where age>30; #指定游標迴圈結束時的返回值 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true; #設置初始值 SET sage = 0; SET total=0; #打開游標 OPEN cur; #開始迴圈游標里的數據 read_loop:loop #根據游標當前指向的一條數據 FETCH cur INTO sid,sname,sage; #判斷游標的迴圈是否結束 IF done THEN LEAVE read_loop; #跳出游標迴圈 END IF; #獲取一條數據時,將count值進行累加操作,這裡可以做任意你想做的操作, SET total = total + 1; #結束游標迴圈 END LOOP; #關閉游標 CLOSE cur; #輸出結果 SELECT total; END CREATE PROCEDURE getTotal() BEGIN DECLARE total INT; ##創建接收游標數據的變數 DECLARE sid INT; DECLARE sname VARCHAR(10); #創建總數變數 DECLARE sage INT; #創建結束標誌變數 DECLARE done INT DEFAULT false; #創建游標 DECLARE cur CURSOR FOR SELECT id,name,age from cursor_table where age>30; #指定游標迴圈結束時的返回值 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true; SET total = 0; OPEN cur; FETCH cur INTO sid, sname, sage; WHILE(NOT done) DO SET total = total + 1; FETCH cur INTO sid, sname, sage; END WHILE; CLOSE cur; SELECT total; END CREATE getTotal() BEGIN DECLARE total INT; ##創建接收游標數據的變數 DECLARE sid INT; DECLARE sname VARCHAR(10); #創建總數變數 DECLARE sage INT; #創建結束標誌變數 DECLARE done INT DEFAULT false; #創建游標 DECLARE cur CURSOR FOR SELECT id,name,age from cursor_table where age > 30; #指定游標迴圈結束時的返回值 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = true; SET total = 0; OPEN cur; REPEAT FETCH cur INTO sid, sname, sage; IF NOT done THEN SET total = total + 1; END IF; UNTIL done END REPEAT; CLOSE cur; SELECT total; END
存儲過程之游標 -
事件:事件是用來執行定時任務的一組SQL集,在時間到時會觸發。以後會相信講解
好了,Mysql的基本教程基本上就是這些了。雖然實例不多,但是可以依據自己動手,然後實現各種理論上的操作,2018-09-10,來自分一樣的Secret608