MySQL 之變量

MySQL 之變量

MySQL 的變量分爲四種: 局部變量用戶變量會話變量全局變量 ,其中局部變量只存在於函數和存儲過程,這裏很少了解。其中 會話變量全局變量 在 MySQL 中統稱爲 系統變量html

用戶變量

基本

顧名思義,就是用戶定義的變量。如何定義變量呢?有兩種方法:mysql

  • SET 方式sql

    # 兩種方式均可以
    SET @variable = expr
    SET @variable := expr
  • SELECT 方式服務器

    # 必須 :=
    SELECT @variable := expr

用戶變量定義備註:session

  1. 未定義變量的初始值爲 null(可不定義變量直接使用,不會報錯)
  2. 變量名對大小寫不敏感
  3. 變量不能在要求字面值的地方使用,好比 select 中的 limit 語句等。
  4. 調用用戶變量的表達式的計算順序其實是未定義的,如 SELECT @a = 0, @a := @a + 1;,兩列均可能是 0 。
  5. 爲用戶變量賦值時,會先肯定表達式的值。如何理解,請看以下代碼:函數

    SET @m = 0;
    SET @m = 3, @n = @m;
    SELECT @n; # 0
  6. 雖然用戶變量的類型能夠動態修改,但不建議這麼操做,由於在交接代碼的時候你可能會有生命危險:p。

做爲變量,都是有做用域的,用戶變量的做用是整個會話,即整個會話間都是有效的。這看起來不錯,但要注意,當使用了鏈接池,自定義的用戶變量又沒有正確初始化,容易出現意想不到的問題。由於它實際上並無被銷燬,依舊記錄者上一次的結果。學習

示例

咱們來一個簡單的示例,實現一個序號的功能,表和數據以下:.net

CREATE TABLE employee (
   id int primary key,
   salary int not null
);

INSERT INTO employee VALUES(1, 100);
INSERT INTO employee VALUES(2, 200);
INSERT INTO employee VALUES(3, 300);

根據以前學習的內容,咱們能夠很快的寫出以下 SQL:code

SELECT salary, (@rowno := @rowno + 1) AS 'rowno'
FROM employee, (SELECT @rowno := 0) r;

沒有問題,一切都和預期同樣,而後咱們加一個 WHERE 條件試試:htm

SELECT salary, (@rowno := @rowno + 1) AS 'rowno'
FROM employee, (SELECT @rowno := 0) r
WHERE @rowno = 0;

理論上來講,這是不該該返回數據的,可是它還就是返回了一條數據,就是 id 爲 1 的那條。
爲何呢? WHERE 條件使用的 @rowno 一直都是同一個值 0 ,它不會由於 SELECT 上修改了就實時響應 。要實現
WHERE 的功能須要改寫成以下:

SELECT salary, rowno
FROM (
    SELECT salary, (@rowno := @rowno + 1) AS 'rowno'
    FROM employee, (SELECT @rowno := 0) r
) m
WHERE rowno = 2;

實際上在 SELECTWHEREGROUP BYORDER BY 中用戶變量都不會按預期操做,它使用的是舊值,不會實時修改。

系統變量

會話變量

會話變量爲服務器爲每一個客戶端鏈接維護的變量。在客戶端鏈接時,使用相應全局變量的當前值對客戶端的會話變量進行初始化。

顧名思義,會話變量的做用域就是一個會話 Session 咯。如何爲會話變量設置值呢?以下:

set session var_name = value;
set @@session.var_name = value;
set var_name = value;

注意,只能爲現有的會話變量設置值,不能建立新的會話變量。那如何獲取會話變量呢?以下:

show session variables;
# 以上代碼會把全部會話變量羅列出來,可經過 like 進行過濾
show session variables LIKE "%var%";

全局變量

全局變量會影響服務器總體操做。可是一旦重啓,這些設置會被重置。注意要想更改全局變量,必須具備SUPER權限。

它的設置和會話變量的設置是相似的:

set global var_name = value;
set @@global.var_name = value;

全局變量也不能新增變量,只能修改已有的。而獲取全局變量的操做也是和會話變量相似:

show session variables;
show global variables like "%var%";

文章如有問題,歡迎在評論區中指正。


參考:

相關文章
相關標籤/搜索