自定義變數和語句結束分隔符

2022-06-20 03:57:08 字數 4686 閱讀 5271

有時候為了完成乙個常用的功能需要執行許多條語句,每次都在客戶端裡一條一條的去輸入這麼多語句是很煩的,我們希望有一種批處理的形式,讓我們以很簡單的方式一次性的執行完這些語句,mysql 中的儲存程式本質上封裝了一些可執行的語句,然後給使用者提供一種簡單的呼叫方式來執行這些語句。根據呼叫方式的不同,可以把儲存程式分為儲存例程、觸發器和事件這幾種型別。其中,儲存例程又可以被細分為儲存函式和儲存過程。畫個圖表示一下:

在正式介紹儲存程式之前,需要先了解一下 mysql 中的自定義變數和復合語句的概念。

變數是和常量相對的,一般的程式語言都提供對變數的支援,mysql 中對自定義的變數的命名有個要求,那就是變數名稱前必須加乙個@符號。自定義變數的值的型別可以是任意 mysql 支援的型別,比方說來自定義乙個變數:

mysql> set @a = 1;

query ok, 0 rows affected (0.00 sec)

自定義了乙個名叫 a 的變數,並且把整數 1 賦值給這個變數。如果想檢視這個變數的值的話,使用 select 語句就好了,不過仍然需要在變數名稱加乙個@符號:

mysql> select @a;

+------+

| @a |

+------+

| 1 |

+------+

1 row in set (0.00 sec)

同乙個變數也可以儲存儲存不同型別的值,比方說再把乙個字串值賦值給變數 a:

mysql> set @a = '哈哈哈';

query ok, 0 rows affected (0.00 sec)

除了把乙個常量賦值給乙個變數以外,還可以把乙個變數賦值給另乙個變數:

mysql> set @b = @a;

query ok, 0 rows affected (0.00 sec)

mysql> select @b;

+-----------+

| @b |

+-----------+

| 哈哈哈 |

+-----------+

1 row in set (0.00 sec)

這樣變數 a 和 b 就有了相同的值'哈哈哈'還可以將某個查詢的結果賦值給乙個變數,前提是這個查詢的結果只有乙個值:

mysql> set @a = (select m1 from t1 limit 1);

query ok, 0 rows affected (0.00 sec)

還可以用另一種形式的語句來將查詢的結果賦值給乙個變數:

mysql> select n1 from t1 limit 1 into @b;

query ok, 1 row affected (0.00 sec)

因為語句select m1 from t1 limit 1select n1 from t1 limit 1的查詢結果都只有乙個值,所以它們可以直接賦值給變數 a 或者 b。可以檢視一下這兩個變數的值:

mysql> select @a, @b;

+------+------+

| @a | @b |

+------+------+

| 1 | a |

+------+------+

1 row in set (0.00 sec)

如果查詢結果是一條記錄,該記錄中有多個列的值的話,想把這幾個值分別賦值到不同的變數中,就只能使用into語句了:

mysql> select m1, n1 from t1 limit 1 into @a, @b;

query ok, 1 row affected (0.00 sec)

這條查詢語句只得到一條記錄,把這條記錄的 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 客戶端檢測輸入結束用的符號和分隔各個語句的符號是一樣的!其實也可以用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)

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)

這裡採用了eof作為 mysql 客戶端檢測輸入結束的符號,當然,這個只是為了方便一次性輸入多個語句,在輸入完成之後最好還是改回常用的分號

mysql> delimiter ;

自定義Shell分隔符

在shell中使用for迴圈語句時,引數列表有時候需要將空格納入引數當中,這時就不好使用空格作為分隔符。如下例中,我實際想要輸出的是a1 a2 b1 b2以及hello world,但卻輸出了如下內容 root youxi1 vim a.sh bin bash list a1 a2 b1 b2 he...

SQL語句中,自定義變數的妙用

我們在按日期統計每天的資料時,有時候會想統計截止到每一天的總量。固然可以通過一張輔助表 儲存了所需要的所有日期 來達到目的,可效率太低,影響查詢速度。今天分享乙個效率高 用法簡單的方式 自定義變數!廢話少說,直接上碼 select a.day,a.num,total total num from s...

Mysql sql的系統變數和自定義變數

sql的變數 系統變數 是資料庫系統自己提供的 全域性變數global 開啟任何客戶端 都有效 會話變數session 針對乙個會話或一次連線 自定義變數 使用者變數 區域性變數 一 系統變數 說明 變數有系統提供,不是使用者定義,屬於伺服器層面 注意 如果時全域性級別,則需加global,如果是回...