有時候爲了完成一個經常使用的功能須要執行許多條語句,每次都在客戶端裏一條一條的去輸入這麼多語句是很煩的,咱們但願有一種批處理的形式,讓咱們以很簡單的方式一次性的執行完這些語句,MySQL
中的存儲程序
本質上封裝了一些可執行的語句,而後給用戶提供一種簡單的調用方式來執行這些語句,根據調用方式的不一樣,咱們能夠把存儲程序
分爲存儲例程
、觸發器
和事件
這幾種類型。其中,存儲例程
又能夠被細分爲存儲函數
和存儲過程
。咱們畫個圖表示一下:mysql
在正式介紹存儲程序
以前,咱們須要先了解一下MySQL
中的自定義變量和複合語句的概念。程序員
變量
是和常量
相對的,通常的程序語言都提供對變量的支持,MySQL
中對咱們自定義的變量的命名有個要求,那就是變量名稱前必須加一個@
符號。咱們自定義變量的值的類型能夠是任意MySQL
支持的類型,比方說咱們來自定義一個變量:sql
mysql> SET @a = 1;
Query OK, 0 rows affected (0.00 sec)
mysql>
複製代碼
咱們自定義了一個名叫a
的變量,而且把整數1
賦值給這個變量。若是咱們想查看這個變量的值的話,使用SELECT
語句就行了,不過仍然須要在變量名稱加一個@
符號:bash
mysql> SELECT @a;
+------+
| @a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql>
複製代碼
同一個變量也能夠存儲存儲不一樣類型的值,比方說咱們再把一個字符串值賦值給變量a
:服務器
mysql> SET @a = '哈哈哈';
Query OK, 0 rows affected (0.00 sec)
mysql>
複製代碼
除了把一個常量賦值給一個變量之外,咱們還能夠把一個變量賦值給另外一個變量:函數
mysql> SET @b = @a;
Query OK, 0 rows affected (0.00 sec)
mysql> select @b;
+-----------+
| @b |
+-----------+
| 哈哈哈 |
+-----------+
1 row in set (0.00 sec)
mysql>
複製代碼
這樣變量a
和b
就有了相同的值'哇哈哈'
!學習
咱們還能夠將某個查詢的結果賦值給一個變量,前提是這個查詢的結果只有一個值:優化
mysql> SET @a = (SELECT m1 FROM t1 LIMIT 1);
Query OK, 0 rows affected (0.00 sec)
mysql>
複製代碼
還能夠用另外一種形式的語句來將查詢的結果賦值給一個變量:ui
mysql> SELECT n1 FROM t1 LIMIT 1 INTO @b;
Query OK, 1 row affected (0.00 sec)
mysql>
複製代碼
由於語句SELECT m1 FROM t1 LIMIT 1
和SELECT n1 FROM t1 LIMIT 1
的查詢結果都只有一個值,因此它們能夠直接賦值給變量a
或者b
。咱們查看一下這兩個變量的值:spa
mysql> SELECT @a, @b;
+------+------+
| @a | @b |
+------+------+
| 1 | a |
+------+------+
1 row in set (0.00 sec)
mysql>
複製代碼
若是咱們的查詢結果是一條記錄,該記錄中有多個列的值的話,咱們想把這幾個值分別賦值到不一樣的變量中,只能使用INTO
語句了:
mysql> SELECT m1, n1 FROM t1 LIMIT 1 INTO @a, @b;
Query OK, 1 row affected (0.00 sec)
mysql>
複製代碼
這條查詢語句只獲得一條記錄,咱們把這條記錄的m1
列的值賦值到了變量a
中,m2
列的值賦值到了變量b
中。
在MySQL
客戶端的交互界面處,當咱們完成鍵盤輸入並按下回車鍵時,MySQL
客戶端會檢測咱們輸入的內容中是否包含;
、\g
或者\G
這三個符號之一,若是有的話,會把咱們輸入的內容發送到服務器。這樣一來,若是咱們想給服務器發送複合語句(也就是由一條或多條語句組成的語句)的話,就須要把這些語句寫到一行中,好比這樣:
mysql> SELECT * FROM t1 LIMIT 1;SELECT * FROM t2 LIMIT 1;SELECT * FROM t3 LIMIT 1;
+------+------+
| m1 | n1 |
+------+------+
| 1 | a |
+------+------+
1 row in set (0.00 sec)
+------+------+
| m2 | n2 |
+------+------+
| 2 | b |
+------+------+
1 row in set (0.00 sec)
+------+------+
| m3 | n3 |
+------+------+
| 3 | c |
+------+------+
1 row in set (0.00 sec)
mysql>
複製代碼
形成這一不便的緣由在於,MySQL
客戶端檢測輸入結束用的符號和分隔各個語句的符號是同樣的!其實咱們也能夠用delimiter
命令來自定義MySQL
的檢測輸入結束的符號,好比這樣:
mysql> delimiter $
mysql> SELECT * FROM t1 LIMIT 1;
-> SELECT * FROM t2 LIMIT 1;
-> SELECT * FROM t3 LIMIT 1;
-> $
+------+------+
| m1 | n1 |
+------+------+
| 1 | a |
+------+------+
1 row in set (0.00 sec)
+------+------+
| m2 | n2 |
+------+------+
| 2 | b |
+------+------+
1 row in set (0.00 sec)
+------+------+
| m3 | n3 |
+------+------+
| 3 | c |
+------+------+
1 row in set (0.00 sec)
mysql>
複製代碼
delimiter $
命令意味着修改MySQL
客戶端檢測輸入結束的符號爲$
,因此雖然咱們連續輸入了3個以分號;
結尾的查詢語句而且按了回車鍵,輸入的內容並無被提交,直到敲下$
符號並回車,MySQL
客戶端纔會將咱們輸入的內容提交到服務器,此時咱們輸入的內容裏已經有3個獨立的查詢語句了,因此返回了3個結果集。
咱們可使用任何符號來做爲MySQL
客戶端檢測輸入結束的符號,也包括多個字符,好比這樣:
mysql> delimiter EOF
mysql> SELECT * FROM t1 LIMIT 1;
-> SELECT * FROM t2 LIMIT 1;
-> SELECT * FROM t3 LIMIT 1;
-> EOF
+------+------+
| m1 | n1 |
+------+------+
| 1 | a |
+------+------+
1 row in set (0.00 sec)
+------+------+
| m2 | n2 |
+------+------+
| 2 | b |
+------+------+
1 row in set (0.00 sec)
+------+------+
| m3 | n3 |
+------+------+
| 3 | c |
+------+------+
1 row in set (0.00 sec)
mysql>
複製代碼
咱們這裏採用了EOF
做爲MySQL
客戶端檢測輸入結束的符號,是否是很easy啊!固然,這個只是爲了方便咱們一次性輸入多個語句,在輸入完成以後最好仍是改回咱們經常使用的分號;
吧:
mysql> delimiter ;
複製代碼
本系列專欄都是MySQL入門知識,想看進階知識能夠到小冊中查看:《MySQL是怎樣運行的:從根兒上理解MySQL》的連接 。小冊的內容主要是從小白的角度出發,用比較通俗的語言講解關於MySQL進階的一些核心概念,好比記錄、索引、頁面、表空間、查詢優化、事務和鎖等,總共的字數大約是三四十萬字,配有上百幅原創插圖。主要是想下降普通程序員學習MySQL進階的難度,讓學習曲線更平滑一點~