MySQL 筆記6 -- 函式與事務
阿新 • • 發佈:2018-12-20
MySQL 筆記6 – 函式與事務
MySQL 系列筆記是筆者學習、實踐MySQL資料庫的筆記
一、內建函式
1、函式
- 事先編寫的實現某些功能的程式碼集合,可以直接呼叫
- 函式可以用在SELECT語句及其子句,也可以用在UPDATE,DELETE語句當中
- 格式:SELECT 函式
- 函式分類:字串函式、數值函式、日期和時間函式、流程函式、其它函式
2、字串函式
函式 | 說明 |
---|---|
COMCAT(s1,s2…sn) | 將傳入的字元連線成一個字串,任何字串與null進行連線結果都是null |
INSERT(str,x,y,instr) | 將字串str從x(從1開始)位置開始,y個字元長的子串替換為instr |
LOWER(Str)/UPPER(str) | 將字串轉成小/大寫 |
LEFT(str,x)/RIGHT(str,x) | 返回字串最左/右邊的x個字元,x=null 不返回任何字元 |
LPAD(str,n,pad)/RPAD(str,n,pad) | 用字串pad對str最左/右邊進行填充,直到長度為n個字元 |
REPEAT(str,x) | 返回str重複x次的結果 |
REPLACE(str,a,b) | 用字串b替換字串str中所有出現的字串a |
SUBSTRING(str,x,y) | 返回字串str中第x位置起y個字元長度的字元 |
3、數值函式
函式 | 說明 |
---|---|
ABS(x) | 返回X的絕對值 |
CEIL(x) | 小數不為零部分上取整,即向上取最近的整數 |
FLOOR(x) | 小數部分下取整,即向下取最近的整數 |
MOD(X,Y) | 返回X/Y的模 |
RAND() | 返回0-1的隨機值 |
RAND()*n | 返回0-n的隨機值 |
4、日期和時間函式
函式:
函式 | 說明 |
---|---|
CURDATE() | 返回當前日期,只包含年月日 |
CURTIME() | 返回當前時間,只包含時分秒 |
NOW() | 返回當前日期和時間,年月日時分秒都包含 |
UNIX_TIMESTAMP | 返回當前日期的時間戳 |
FROM_UNIXTIME(unixtime) | 將一個時間戳轉換成日期 |
WEEK(DATE) | 返回當前是一年中的第幾周 |
YEAR(DATE) | 返回所給日期是那一年 |
HOUR(TIME) | 返回當前時間的小時 |
MINUTE(TIME) | 返回當前時間的分鐘 |
DATE_FORMAT(date,fmt) | 按字串格式化日期date值 |
DATE_ADD(date,interval expr type) | 計算日期相加 |
DATEDIFF(date1,date2) | 計算兩個日期相差的天數 |
格式化日期的格式符:
- 用在fmt中,形如’%M%D%Y’
- 可以在格式符中插入自定義的符號,形如’%M-%D-%Y’
格式符 | 說明 |
---|---|
%a | 縮寫星期名 |
%b | 縮寫月名 |
%c | 月,數值 |
%D | 帶有英文字首的月中的天 |
%d | 月的天,數值(00-31) |
%e | 月的天,數值(0-31) |
%f | 微秒 |
%H | 小時 (00-23) |
%h | 小時 (01-12) |
%I | 小時 (01-12) |
%i | 分鐘,數值(00-59) |
%j | 年的天 (001-366) |
%k | 小時 (0-23) |
%l | 小時 (1-12) |
%M | 月名 |
%m | 月,數值(00-12) |
%p | AM 或 PM |
%r | 時間,12-小時(hh:mm:ss AM 或 PM) |
%S | 秒(00-59) |
%s | 秒(00-59) |
%T | 時間, 24-小時 (hh:mm:ss) |
%U | 周 (00-53) 星期日是一週的第一天 |
%u | 周 (00-53) 星期一是一週的第一天 |
%V | 周 (01-53) 星期日是一週的第一天,與 %X 使用 |
%v | 周 (01-53) 星期一是一週的第一天,與 %x 使用 |
%W | 星期名 |
%w | 周的天 (0=星期日, 6=星期六) |
%X | 年,其中的星期日是周的第一天,4 位,與 %V 使用 |
%x | 年,其中的星期一是周的第一天,4 位,與 %v 使用 |
%Y | 年,4 位 |
%y | 年,2 位 |
5、流程函式
函式 | 說明 |
---|---|
IF(value,t,f) | 如果value是真,返回t,否則返回f |
IFNULL(value1,value2) | 如果value1不為空,返回value1否者返回value2 |
CASE WHEN value THEN t ELSE f END | 當value是真,返回t,否則返回f |
6、其它函式
函式 | 說明 |
---|---|
DATABASE() | 返回當前資料庫名 |
VERSION() | 返回當前資料庫版本 |
USER() | 返回當前登陸使用者名稱 |
PASSWORD(STR) | 對str進行加密 |
MD5() | 返回str的MD5值 |
二、自定義函式
1、修改命令結束符
- 格式:DELIMITER x,將標準分隔符 ; 更改為自定義的 x
- 因為定義函式時,函式是作為一個整體的,而函式內是多條單獨的語句。為了不讓讓mysql遇到 ;號就解釋語句,需要在定義函式開頭修改分隔符,完成後把分隔符還原為 ;
2、自定義函式
DELIMITER 自定義分隔符
CREATE FUNCTION 函式名 RETURNS 資料型別
begin
語句1;
語句2;
....
return 和要求的資料型別一樣的資料;
end 自定義分隔符
DELIMITER ;
- 呼叫自定義函式格式跟內建函式一致
三、事務
1、事務
- 不可分割的操作,假設某操作有多個步驟組成,其中任意一個步驟操作失敗,則認為事務失敗,所有步驟全完成該操作才是成功
- 每條SQL語句都是一個事務,可以把多條SQL語句定義成一個事務
- 事務只對DML語句有效,對於DQL無效
2、事務的ACID
- 原子性(Atomicity):事務包含的所有操作要麼全部成功,要麼全部失敗回滾
- 一致性(Consistency):事務必須使資料庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之後都必須處於一致性狀態,讓資料保持一定上的合理,如:一個商品出庫時,倉庫商品數量減1,對應使用者的購物車中商品加1
- 隔離性(Isolation):當多個使用者併發訪問資料庫時,比如操作同一張表時,資料庫為每一個使用者開啟的事務,不能被其他事務的操作所幹擾,多個併發事務之間要相互隔離
- 永續性(Durability):一個事務一旦被提交了,就不能再回滾了,已經把資料儲存到資料庫當中了
3、事務的使用
操作 | 語句 | 說明 |
---|---|---|
開啟事務 | start transaction | |
回滾事務 | rollback | 銷執行的sql語句,必須在提交事務之前 |
提交事務 | commit | 事務中的所有語句全部執行完畢時提交事務,若沒有發生異常,更新到資料庫中 |
4、事務隔離級別
隔離級別:
級別 | 說明 |
---|---|
Read uncommitted(讀未提交) | 一個事務可以讀取另一個未提交事務的資料 |
Read committed(讀已提交) | 一個事務要等另一個事務提交後才能讀取資料 |
Repeatable read(可重複讀) | 就是在開始讀取資料(事務開啟)時,不再允許修改操作 |
Serializable(序列) | 在該級別下,事務序列化順序執行,可以避免髒讀、不可重複讀與幻讀 |
檢視隔離級別:
- select @@global.tx_isolation,@@tx_isolation;
設定隔離級別:
- 全域性的:set global transaction isolation level 隔離級別;
- 當前會話: set session transaction isolation level 隔離級別;
5、事務的併發
問題:
問題 | 說明 |
---|---|
髒讀 | 一事務可以看到了另一事務正在修改但還未提交的改變 |
不可重複讀 | 一次會話的同一事務的多次相同查詢返回了不同資料(其它事務的提交修改了) |
重複讀 | 一個事務進行UPDATE修改操作時,其它事務不能執行UPDATE操作 |
幻讀 | 一個會話的事務(已提交)重新整理了資料庫,另一會話前後兩次的查詢事務顯示的資訊不一致 |
各隔離級別會出現的問題:
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
Read uncommitted | 是 | 是 | 是 |
Read committed | 否 | 是 | 是 |
Repeatable read | 否 | 否 | 是 |
Serializable | 否 | 否 | 否 |
GOOD LUCK!