## 一列赎、兩個引擎的對比
### MyISAM
- 不支持事務(wù)垛贤,但是整個操作是原子性的(事務(wù)具備四種特性:原子性、一致性唤崭、隔離性棕孙、持久性)
- 不支持外鍵舔亭,支持表鎖,每次鎖住的是整張表
MyISAM的表鎖有讀鎖和寫鎖(<font color='red'>兩個鎖都是表級別</font>)
一個MyISAM表有三個文件:索引文件蟀俊,表結(jié)構(gòu)文件分歇,數(shù)據(jù)文件
存儲表的總行數(shù),執(zhí)行<font color='orange'>select count(*) from table</font>時只要簡單的讀出保存好的行數(shù)即可
采用非聚集索引欧漱,索引文件的數(shù)據(jù)域存儲指向數(shù)據(jù)文件的指針。輔索引與主索引基本一致葬燎,但是輔索引不用保證唯一性误甚。
<font color='red'>對于AUTO_INCREMENT類型的字段缚甩,在MyISAM表中,可以和其他字段一起建立聯(lián)合索引窑邦。</font>
### InnoDB
- 支持事務(wù)擅威,支持事務(wù)的四種隔離級別;是一種具有事務(wù)(commit)、回滾(rollback)和崩潰修復(fù)能力(crash recovery capabilities)的事務(wù)安全(transaction-safe (ACID compliant))型表冈钦。
- 支持行鎖和外鍵約束郊丛,因此可以支持寫并發(fā)
- 不存儲總行數(shù);也就是說瞧筛,執(zhí)行select count(*) from table時厉熟,InnoDB要掃描一遍整個表來計算有多少行。注意的是较幌,當(dāng)count(*)語句包含 where條件時揍瑟,兩種表的操作是一樣的。
- 對于AUTO_INCREMENT類型的字段乍炉,InnoDB中必須包含只有該字段的索引
- DELETE FROM table時绢片,InnoDB不會重新建立表,而是一行一行的刪除
- 一個Innodb表存儲在一個文件內(nèi)(共享表空間岛琼,表大小不受操作系統(tǒng)的限制)底循,也可能為多個(設(shè)置為獨立表空間,表大小受操作系統(tǒng)限制槐瑞,大小為2G)熙涤,受操作系統(tǒng)文件大小的限制
- 主鍵索引采用聚集索引(索引的數(shù)據(jù)域存儲數(shù)據(jù)文件本身),輔索引的數(shù)據(jù)域存儲主鍵的值随珠;因此從輔索引查找數(shù)據(jù)灭袁,需要先通過輔索引找到主鍵值,再訪問主鍵索引窗看;最好使用自增主鍵茸歧,防止插入數(shù)據(jù)時,為維持B+樹結(jié)構(gòu)显沈,文件的大調(diào)整软瞎。
? ### 兩者的區(qū)別
![img](12.11.assets/1266222-20181002095044128-1277628264.png)
## 二、MySQL磁盤碎片
### 碎片產(chǎn)生的原因
- <font color='orange'>表的存儲會出現(xiàn)碎片化</font>拉讯,每當(dāng)刪除了一行內(nèi)容涤浇,該段空間就會變?yōu)榭瞻住⒈涣艨漳Э叮谝欢螘r間內(nèi)的大量刪除操作只锭,會使這種留空的空間變得比存儲列表內(nèi)容所使用的空間更大;
- 當(dāng)執(zhí)行插入操作時院尔,MySQL會嘗試使用空白空間蜻展,但如果某個空白空間一直沒有被大小合適的數(shù)據(jù)占用喉誊,仍然無法將其徹底占用,就形成了碎片纵顾;
- 當(dāng)MySQL對數(shù)據(jù)進(jìn)行掃描時伍茄,它掃描的對象實際是列表的容量需求上限,也就是數(shù)據(jù)被寫入的區(qū)域中處于峰值位置的部分
如:<font color='orange'>一個表有1萬行施逾,每行10字節(jié)敷矫,會占用10萬字節(jié)存儲空間,執(zhí)行刪除操作汉额,只留一行曹仗,實際內(nèi)容只剩下10字節(jié),但MySQL在讀取時闷愤,仍看做是10萬字節(jié)的表進(jìn)行處理整葡,所以,碎片越多讥脐,就會越來越影響查詢性能遭居。</font>
#### 查看表碎片的大小:
```MySQL
show table status like '表名';
```
結(jié)果中'Data_free'列的值就是碎片大小
![img](12.11.assets/20171019111511165.png)
#### 列出所有已經(jīng)產(chǎn)生碎片的表:
```MySQL
select table_schema db, table_name, data_free, engine from information_schema.tables where table_schema not in ('information_schema', 'mysql') and data_free > 0;
```
#### 清理表碎片
1. MyISAM表:
? ```MySQL
? optimize table 表名;
? ```
2. InnoDB表:
? ```MySQL
? alter table 表名 engine = InnoDB;
? ```
? ## 三旬渠、數(shù)據(jù)庫優(yōu)化
<font color='orange'>是否需要清理碎片俱萍、上的鎖是否為表鎖</font>
<font color='orange'>select后不要用*,不然會回表</font>
#### 選取最適用的字段屬性
<font color='red'>數(shù)據(jù)庫中的表越小告丢,在它上面執(zhí)行的查詢也就會越快枪蘑。</font>因此,在創(chuàng)建表的時候岖免,為了獲得更好的性能岳颇,我們可以將表中字段的寬度設(shè)得盡可能小
**另外一個提高效率的方法是在可能的情況下,應(yīng)該盡量把字段設(shè)置為NOT NULL**颅湘,這樣在將來執(zhí)行查詢的時候话侧,數(shù)據(jù)庫<font color='red'>不用去比較NULL值</font>
因為在MySQL中,ENUM類型被當(dāng)作數(shù)值型數(shù)據(jù)來處理闯参,而數(shù)值型數(shù)據(jù)被處理起來的速度要比文本類型快得多
#### 使用連接(JOIN)來代替子查詢(Sub-Queries)
使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的SQL操作瞻鹏,同時也可以<font color='red'>避免事務(wù)或者表鎖死</font>,并且寫起來也很容易鹿寨。但是新博,有些情況下,<font color='red'>子查詢可以被更有效率的連接(JOIN)替代</font>脚草。
#### 使用聯(lián)合(UNION)來代替手動創(chuàng)建的臨時表(不懂)
可以把需要使用臨時表的兩條或更多的<font color='orange'>select</font>查詢合并的一個查詢中赫悄。在客戶端的查詢會話<font color='red'>結(jié)束的時候</font>,臨時表會被<font color='red'>自動刪除</font>,從而保證數(shù)據(jù)庫整齊涩蜘、高效
用union來創(chuàng)建查詢的時候嚼贡,我們只需要用UNION作為關(guān)鍵字把多個select語句連接起來就可以了,要注意的是所有select語句中的字段數(shù)目要想同同诫。
#### 事務(wù)
事務(wù)原理是:<font color='red'>要么語句塊中每條語句都操作成功,要么都失敗</font>樟澜。換句話說误窖,<font color='orange'>就是可以保持?jǐn)?shù)據(jù)庫中數(shù)據(jù)的一致性和完整性</font>。事物以<font color='orange'>BEGIN</font>關(guān)鍵字開始秩贰,<font color='orange'>COMMIT</font>關(guān)鍵字結(jié)束霹俺。在這之間的一條SQL操作失敗,那么毒费,<font color='orange'>rollback</font>命令就可以把數(shù)據(jù)庫恢復(fù)到<font color='orange'>BEGIN</font>開始之前的狀態(tài)丙唧。
<font color='cornflowerblue'>事務(wù)的另一個重要作用是當(dāng)多個用戶同時使用相同的數(shù)據(jù)源時,它可以利用鎖定數(shù)據(jù)庫的方法來為用戶提供一種安全的訪問方式觅玻,這樣可以保證用戶的操作不被其它的用戶所干擾想际。</font>
#### 鎖定表
盡管事務(wù)是維護數(shù)據(jù)庫完整性的一個非常好的方法,但卻因為它的<font color='red'>獨占性</font>溪厘,有時會影響數(shù)據(jù)庫的性能胡本,尤其是在很大的應(yīng)用系統(tǒng)中。<font color='red'>由于在事務(wù)執(zhí)行的過程中畸悬,數(shù)據(jù)庫將會被鎖定</font>侧甫,因此其它的用戶請求<font color='red'>只能暫時等待直到該事務(wù)結(jié)束</font>。如果一個數(shù)據(jù)庫系統(tǒng)只有少數(shù)幾個用戶來使用蹋宦,事務(wù)造成的影響不會成為一個太大的問題披粟;但假設(shè)有成千上萬的用戶同時訪問一個數(shù)據(jù)庫系統(tǒng),就會產(chǎn)生比較嚴(yán)重的響應(yīng)延遲冷冗。此時通過<font color='red'>鎖定表</font>的方法來獲得更好的性能
#### 使用外鍵
鎖定表的方法可以<font color='red'>維護數(shù)據(jù)的完整性</font>守屉,但是它<font color='red'>卻不能保證數(shù)據(jù)的關(guān)聯(lián)性</font>。這個時候我們就可以使用<font color='orange'>外鍵</font>贾惦。
#### 使用索引
索引是提高數(shù)據(jù)庫性能的常用方法胸梆,它可以令數(shù)據(jù)庫服務(wù)器以比沒有索引快得多的速度檢索特定的行,尤其是在查詢語句當(dāng)中包含有<font color='red'>MAX()</font>,<font color='red'>MIN()</font>和<font color='red'>ORDERBY</font>這些命令的時候须板,性能提高更為明顯碰镜。
一般說來,索引應(yīng)建立在那些將用于<font color='red'>JOIN,WHERE</font>判斷和<font color='red'>ORDER BY</font>排序的字段上习瑰。盡量不要對數(shù)據(jù)庫中某個含有大量重復(fù)的值的字段建立索引绪颖。
#### 優(yōu)化的查詢語句
絕大多數(shù)情況下,使用索引可以提高查詢的速度,但如果<font color='red'>SQL語句使用不恰當(dāng)?shù)脑?lt;/font>柠横,索引將無法發(fā)揮它應(yīng)有的作用窃款。
- 不能將一個建有索引的<font color='orange'>int</font>字段和<font color='orange'>bigint</font>字段進(jìn)行比較;但是作為特殊的情況牍氛,在<font color='orange'>CHAR</font>類型的字段和<font color='orange'>VARCHAR</font>類型字段的字段大小相同的時候晨继,可以將它們進(jìn)行比較。
- 在建有索引的字段上盡量<font color='orange'>不要使用函數(shù)</font>進(jìn)行操作
- 在搜索字符型字段時搬俊,我們有時會使用<font color='red'>LIKE關(guān)鍵字和通配符</font>紊扬,這種做法雖然簡單,但卻也是<font color='red'>以犧牲系統(tǒng)性能為代價</font>的唉擂。
## 四餐屎、慢查詢?nèi)罩?/p>
MySQL的慢查詢?nèi)罩臼荕ySQL提供的一種日志記錄,它用來記錄在MySQL中響應(yīng)時間超過閥值的語句玩祟,具體指運行時間超過<font color='orange'>long_query_time</font>(<font color='red'>long_query_time的默認(rèn)值為10腹缩,意思是運行10S以上的語句</font>)值的SQL,則會被記錄到慢查詢?nèi)罩局小?/p>
#### 慢查詢?nèi)罩鞠嚓P(guān)參數(shù)
```MySQL
slow_query_log:是否開啟慢查詢?nèi)罩荆?表示開啟空扎,0表示關(guān)閉藏鹊。
show variables like '%slow_query_log';
slow-query-log-file:MySQL數(shù)據(jù)庫慢查詢?nèi)罩敬鎯β窂健勺卢?梢圆辉O(shè)置該參數(shù)伙判,系統(tǒng)則會默認(rèn)給一個缺省的文件host_name-slow.log
show variables like '%slow_query_log-file';
long_query_time :慢查詢閾值,當(dāng)查詢時間多于設(shè)定的閾值時黑忱,記錄日志宴抚。
show VARIABLES like 'long_query_time%';
log_queries_not_using_indexes:未使用索引的查詢也被記錄到慢查詢?nèi)罩局校蛇x項)。
show variables like '%log_queries_not_using_indexes';
```
<font color='red'>log_output</font>:日志存儲方式甫煞。<font color='red'>log_output='FILE'</font>表示將<font color='orange'>日志存入文件菇曲,默認(rèn)值是'FILE'。</font><font color='red'>log_output='TABLE'</font>表示將<font color='orange'>日志存入數(shù)據(jù)庫</font>抚吠,這樣日志信息就會被寫入到<font color='orange'>mysql.slow_log表</font>中常潮。MySQL數(shù)據(jù)庫支持同時兩種日志存儲方式,配置的時候以逗號隔開即可楷力,如:<font color='orange'>log_output='FILE,TABLE'喊式。</font>日志記錄到系統(tǒng)的專用日志表中,要比記錄到文件耗費更多的系統(tǒng)資源萧朝,因此對于需要啟用慢查詢?nèi)罩静砹簦中枰軌颢@得更高的系統(tǒng)性能,那么建議優(yōu)先記錄到文件检柬。
```mysql
查詢慢查詢?nèi)罩敬鎯Ψ椒?/p>
show variables like '%log_output'
修改慢查詢?nèi)罩敬鎯ξ恢?/p>
set global log_output = 'FILE,TABLE'
打印在MySQL中慢查詢?nèi)罩镜奈恢?/p>
SELECT * FROM mysql.slow_log
```
默認(rèn)情況下<font color='orange'>slow_query_log</font>的值為<font color='red'>OFF</font>献联,表示慢查詢?nèi)罩臼墙玫?/p>
<font color='cornflowerblue'>那么開啟了慢查詢?nèi)罩竞螅裁礃拥腟QL才會記錄到慢查詢?nèi)罩纠锩婺兀?lt;/font> 這個是由參數(shù)<font color='orange'>long_query_time</font>控制,默認(rèn)情況下<font color='orange'>long_query_time</font>的值為10秒里逆,可以使用命令修改进胯,也可以在my.cnf參數(shù)里面修改。關(guān)于運行時間正好等于<font color='orange'>long_query_time</font>的情況原押,并不會被記錄下來胁镐。也就是說,在<font color='red'>mysql源碼里是判斷大于long_query_time诸衔,而非大于等于</font>希停。
## 五、本日重點講解(不重要的東西)
可移植性不好署隘,不易調(diào)試
### 1、觸發(fā)器
與表有關(guān)的數(shù)據(jù)對象亚隙,在滿足某種條件的時候磁餐,被動執(zhí)行SQL語句
指事先為某張表<font color='red'>綁定一段代碼</font>,當(dāng)表中的<font color='red'>某些內(nèi)容發(fā)生改變</font>(增阿弃、刪诊霹、改)的時候,系統(tǒng)會<font color='red'>自動觸發(fā)代碼并執(zhí)行</font>渣淳。
#### 作用:
- 可在寫入數(shù)據(jù)前脾还,強制檢驗或者轉(zhuǎn)換數(shù)據(jù)(保證護數(shù)據(jù)安全)
- 觸發(fā)器發(fā)生錯誤時,前面用戶已經(jīng)執(zhí)行成功的操作會被撤銷入愧,類似事務(wù)的回滾
#### 創(chuàng)建觸發(fā)器
基本語句
```MySQL
delimiter 自定義結(jié)束符號
create trigger 觸發(fā)器名字 觸發(fā)時間 觸發(fā)事件 on 表 for each row
begin
? ? -- 觸發(fā)器內(nèi)容主體鄙漏,每行用分號結(jié)尾
end 自定義的結(jié)束符合
```
<font color='orange'>on 表 for each</font>:觸發(fā)對象,觸發(fā)器綁定的實質(zhì)是表中的所有行棺蛛,因此當(dāng)每一行發(fā)生指定改變時怔蚌,觸發(fā)器就會發(fā)生
##### 觸發(fā)時間
當(dāng) SQL 指令發(fā)生時,會令行中數(shù)據(jù)發(fā)生變化旁赊,而每張表中對應(yīng)的行有兩種狀態(tài):**數(shù)據(jù)操作前和操作后**
- before:表中數(shù)據(jù)發(fā)生改變前的狀態(tài)
- after:表中數(shù)據(jù)發(fā)生改變后的狀態(tài)
**PS**:如果 before 觸發(fā)器失敗或者語句本身失敗桦踊,將不執(zhí)行 after 觸發(fā)器(如果有的話)
##### 觸發(fā)事件
觸發(fā)器是針對數(shù)據(jù)發(fā)送改變才會被觸發(fā),對應(yīng)的操作只有
- INSERT:沒有 old终畅,只有 new籍胯,new 表示將要(插入前)或者已經(jīng)增加(插入后)的數(shù)據(jù)
- DELETE:既有 old 也有 new,old 表示更新之前的數(shù)據(jù)离福,new 表示更新之后的數(shù)據(jù)
- UPDATE:沒有 new杖狼,只有 old,old 表示將要(刪除前)或者已經(jīng)被刪除(刪除后)的數(shù)據(jù)
#### 查看觸發(fā)器
1.查看全部觸發(fā)器
```MySQL
show triggers;
```
2.查看觸發(fā)器的創(chuàng)建語句
```MySQL
show create trigger 觸發(fā)器名字;
```
3.觸發(fā)觸發(fā)器
```MySQL
drop trigger 觸發(fā)器名字;
```
#### 刪除觸發(fā)器
觸發(fā)器不能修改术徊,只能刪除
```MySQL
drop trigger + 觸發(fā)器名字
```
### 2本刽、存儲過程
#### 變量
##### 局部變量
局部變量只在<font color='orange'>BEGIN</font>和<font color='orange'>END</font>的代碼塊中有效,執(zhí)行完該代碼塊,變量就消失子寓,在存儲過程中最為常見暗挑。<font color='orange'>DECLARE</font>語句專門用于定義局部變量,可以使用<font color='orange'>DEFAULT</font>語句來指明默認(rèn)值斜友。定義多個變量:<font color='orange'>DECLARE x, y INT DEFAULT 0</font>炸裆。賦值用的是`SET`或`SELECT`語句:
```MySQL
DECLARE total_count INT DEFAULT 0
SET total_count = 10;
SELECT COUNT(*) INTO total_count FROM products
```
其中<font color='orange'>total_count</font>為局部變量
##### 用戶變量
<font color='red'>用戶變量與數(shù)據(jù)庫連接有關(guān)</font>,一個客戶端定義的變量不能被其它客戶端看到或使用鲜屏。當(dāng)客戶端退出時烹看,該客戶端連接的所有變量將失效。用戶變量不需要聲明洛史,可以直接使用惯殊,用戶變量以<font color='orange'>@var_name</font>的形式命名變量,<font color='red'>變量名必須以@開頭</font>也殖。
賦值語法土思,一般用<font color='orange'>SET</font>:
```MySQL
set @varName=value;
SELECT @var_name := value;
```
賦值后輸出用<font color='orange'>select @varName</font>。
##### 系統(tǒng)變量
MySQL可以訪問許多系統(tǒng)變量忆嗜。當(dāng)服務(wù)器運行時許多變量允許動態(tài)更改己儒。這樣就可以修改服務(wù)器操作而不需要停止并重啟服務(wù)器。系統(tǒng)變量又包含兩種:<font color='red'>會話變量影響具體客戶端連接的操作捆毫,全局變量影響服務(wù)器整體操作闪湾。</font>
##### 全局變量
全局變量在 MySQL 啟動的時候由服務(wù)器自動初始化他們的值, 這些默認(rèn)的值可以在<font color='orange'>/etc/my.cnf</font>中修改。要想更改全局變量绩卤,必須具有<font color='red'>SUPER</font>權(quán)限途样。全局變量作用于<font color='red'>SERVER的整個生命周期</font>,<font color='red'>但重啟后所有設(shè)置的全局變量均失效</font>省艳。要想讓全局變量重啟后繼續(xù)生效娘纷,需要更改相應(yīng)的配置文件。
```MySQL
show global variables like 'wait_timeout%';
```
```mysql
更改等待時間
set global wait_timeout=4;
```
#### 存儲過程創(chuàng)建
存儲過程是一組已經(jīng)預(yù)先編譯好的<font color='orange'>sql</font>語句的集合跋炕,理解為批處理語句(增加流程控制語句)赖晶,一般在復(fù)雜邏輯中才會使用存儲過程
<font color='red'>存儲過程的優(yōu)點:</font>
- 提供了代碼的可用性
- 簡化了數(shù)據(jù)庫操作,將業(yè)務(wù)邏輯的細(xì)節(jié)隱藏在存儲過程中
- 減少了編譯次數(shù)辐烂,減少了網(wǎng)絡(luò)IO的次數(shù)遏插,從而提高操作效率
<font color='red'>存儲過程的創(chuàng)建</font>
```cpp
/*
delimiter $
create procedure 存儲過程的名稱(參數(shù)列表)
begin
局部變量的定義
多條sql語句
流程控制語句
eng;$
*/
```
如果存儲過程中只有一條<font color='orange'>sql</font>語句可以省略<font color='orange'>begin end</font>
<font color='red'>參數(shù)列表</font>
| 參數(shù)模式 | 形參名稱 | 參數(shù)類型? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
| :------- | -------- | ------------------------------------------------- |
| in? ? ? | username | MySQL數(shù)據(jù)庫中的數(shù)據(jù)類型(數(shù)值型,字符型纠修,日期型) |
| out? ? ? | pwd? ? ? | MySQL數(shù)據(jù)庫中的數(shù)據(jù)類型(數(shù)值型胳嘲,字符型,日期型) |
| inout? ? | xxx? ? ? | MySQL數(shù)據(jù)庫中的數(shù)據(jù)類型(數(shù)值型扣草,字符型了牛,日期型) |
<font color='red'>in</font>:聲名該參數(shù)是一個輸入型參數(shù)(<font color='orange'>類似Java中的形參</font>)
<font color='red'>out</font>:聲名該參數(shù)為一個輸出型參數(shù)(<font color='orange'>類型Java中的返回值</font>)颜屠,在一個存儲過程中<font color='orange'>可以定義多個out類型的參數(shù)</font>
<font color='red'>inout</font>:聲名該參數(shù)可以為輸入型參數(shù),也可以為輸出型參數(shù)
<font color='red'>存儲過程調(diào)用</font>
```mysql
call 存儲過程的名稱(實參列表)
-- 實參列表中包含由輸出類型的參數(shù)
```
<font color='red'>存儲過程的演示</font>
- 無參的存儲過程
? ```MySQL
? -- 用于b_user表中插入2條數(shù)據(jù)
? delimiter $ -- 自定義結(jié)束標(biāo)志
? create procedure pro_insert()
? begin
? insert into b_user(name,sex) values('1','1');
? insert into b_user(name,sex) values('2','2');
? end;$
? -- 用這個存儲過程
? call pro_insert();
? ```
- 帶有<font color='red'>in</font>模式參數(shù)的存儲過程
? ```MySQL
? -- 用于向b_user插入2條數(shù)據(jù)鹰祸,性別由客戶輸入
? delimiter $
? create procedure pro_insert2(in sex char(1))
? begin
? insert into b_user(name,sex) values('1',sex);
? insert into b_user(name,sex) values('2',sex);
? end;$
? call pro_insert2('男');
? ```
- 帶有多個<font color='red'>in</font>模式參數(shù)的存儲過程
? ```MySQL
? -- 用于向b_user插入2條數(shù)據(jù)甫窟,性別由客戶輸入
? delimiter $
? create procedure pro_insert2(in name varchar(10),in sex char(1))
? begin
? insert into b_user(name,sex) values(name,sex);
? insert into b_user(name,sex) values(name,sex);
? end;$
? call pro_insert2('name','男');
? ```
- 帶<font color='red'>in,out</font>參數(shù)的存儲過程
? ```MySQL
? -- 判斷用戶登錄蛙婴,如果用戶名和密碼輸入正確登錄成功粗井,否則登錄失敗
? -- 根據(jù)輸入的用戶名和密碼作為條件b_user表中查詢,如果查詢總行數(shù)==1街图,則認(rèn)為登錄成功浇衬,讓resukt返回登錄成功;否則登錄失敗
? delimiter $
? create procedure pro_login(in name varchar(20),in pwd varchar(10,out result varchar(20)))
? begin
? declare total int default 0; -- 用于存放查詢總行數(shù)
? select count(*) from b_user u where u.name= name and u.pwd= pwd; -- 將查詢結(jié)果賦值給total局部變量
? set result:= if(total=1,'登錄成功','登錄失敗');
? end;$
? -- 存儲過程如何執(zhí)行
? -- 解決判斷餐济,使用自定義變量
? set @result:='';
? call pro_login('李四','123',@result);
? select @result;
? ```
- 刪除存儲過程
? ```MySQL
? drop procedure 存儲過程名稱
? ```
- 查看存儲過程
? ```MySQL
? show create procedure 存儲過程名稱;
? ```
- 修改存儲過程
? ```MySQL
? drop
? create
? ```
#### 流程控制語句
- <font color='red'>if</font>函數(shù)結(jié)構(gòu)
? ```cpp
? /*
? if 邏輯表達(dá)式 then 語句1;
? elseif 邏輯表達(dá)式2 then 語句2;
? …………
? else 語句n;
? end if;
? */
? ```
- <font color='red'>case</font>結(jié)構(gòu)
? 等值選擇
? ```MySQL
? case 字段|變量|表達(dá)式
? when 值 then 值|語句
? when 值 then 值
? …………
? else 值
? end
? ```
? 不等值選擇
? ```MySQL
? case
? when 邏輯表達(dá)式 then 語句1
? ……
? else 語句n
? end
? ```
- <font color='red'>循環(huán)結(jié)構(gòu)</font>
? while
? ```mysql
? /*
? while 邏輯表達(dá)式 do
? 循環(huán)體
? end while;
? */
? -- 需求:創(chuàng)建存儲過程耘擂,輸入一個值,返回1到該值的和
? delimiter $
? create procedure pro_sum(in input int,out total int)
? begin
? declare i int default 1;
? declare sum_ int default 0;
? while i<=input do
? set sum_=sum_+i;
? set i=i+1;
? end while;
? set total:=sum_;
? end;$
? set @result:=0;
? call pro_sum(10,@result);
? select @result;
? ```
- repeat
? ```mysql
? repeat
? 循環(huán)體
? until 邏輯表達(dá)式 -- 當(dāng)滿足邏輯表達(dá)式絮姆,跳出循環(huán)
? end repeat;
? delimiter $
? create procedure pro_sum_loop(in input int,out total int)
? begin
? declare i int default 1;
? declare sum_ int default 0;
? repeat
? set sum_:=sum_+i;
? set i:=i+1;
? until i>input
? end REPEAT;
? set total:=sum_;
? end;$
? set @result:=0;
? call pro_sum(10,@result);
? select @result;
? ```
### 3梳星、存儲函數(shù)
##### 1. 存儲函數(shù):
- 函數(shù)(Function)為一命名的存儲程序,可帶參數(shù),并返回一計算值.
- 函數(shù)和過程的結(jié)構(gòu)類似,但必須有一個return子句,用于返回函數(shù)值.
##### 2. 創(chuàng)建存儲函數(shù)的語法:
```kotlin
create [or replace] function 函數(shù)名(參數(shù)列表)
return 函數(shù)值類型
as
PLSQL子程序體;
```
<font color='red'>注意事項:</font>
- (1) 與存儲過程注意事項類似,不同的是,**必須有個返回值**;
- (2) 參數(shù)列表可以有,也可以沒有.當(dāng)沒有時,函數(shù)名后面不要帶括號.
```rust
create or replace function queryempannal(pempno in number)
return number
as
? psal emp.sal%type;
? pcomm emp.comm%type;
begin
? select sal,comm into psal,pcomm from emp where empno=pempno;
? return psal*12+nvl(pcomm,0);
end;
```
刪除函數(shù):
```MySQL
drop function 函數(shù)名;
```
### 4、定時任務(wù)
#### 查看任務(wù)是否開啟
```MySQL
show variables like '%event_sche%';
```
開啟定時策略
```MySQL
set global event_scheduler=1;
```
#### 創(chuàng)建定時任務(wù)
```MySQL
create event run_event
on schedule every 1 minute
on completion preserve disable
do call test_procedure ();
```
- create event day_event:是創(chuàng)建名為run_event的事件
- 創(chuàng)建周期定時的規(guī)則滚朵,意思是每分鐘執(zhí)行一次
- on completion preserve disable是表示創(chuàng)建后并不開始生效。
- do call test_procedure ()是該event(事件)的操作內(nèi)容
#### 定時任務(wù)操作
查看
```MySQL
SELECT event_name,event_definition,interval_value,interval_field,status
FROM information_schema.EVENTS;
```
開啟或關(guān)閉
```MySQL
alter event run_event on completion preserve enable;//開啟定時任務(wù)
alter event run_event on completion preserve disable;//關(guān)閉定時任務(wù)
```
#### 定時規(guī)則
周期執(zhí)行–關(guān)鍵字 EVERY
單位有:<font color='red'>second前域、minute辕近、hour、day匿垄、week(周)移宅、quarter(季度)、month椿疗、year</font>
```MySQL
on schedule every 1 week //每周執(zhí)行1次
```