標籤:

MYSQL的用戶變數和系統變數

9.3. 用戶變數

可以先在用戶變數中保存值然後在以後引用它;這樣可以將值從一個語句傳遞到另一個語句。用戶變數與連接有關。也就是說,一個客戶端定義的變數不能被其它客戶端看到或使用。當客戶端退出時,該客戶端連接的所有變數將自動釋放。

用戶變數的形式為@var_name,其中變數名var_name可以由當前字符集的文字數字字元、『.』、『_』和『$』組成。 默認字符集是cp1252 (Latin1)。可以用mysqld的--default-character-set選項更改字符集。參見5.10.1節,「數據和排序用字符集」。用戶變數名對大小寫不敏感。

設置用戶變數的一個途徑是執行SET語句:

SET @var_name = expr [, @var_name = expr] ...

對於SET,可以使用=或:=作為分配符。分配給每個變數的expr可以為整數、實數、字元串或者NULL值。

也可以用語句代替SET來為用戶變數分配一個值。在這種情況下,分配符必須為:=而不能用=,因為在非SET語句中=被視為一個比較 操作符:

mysql> SET @t1=0, @t2=0, @t3=0;mysql> SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;+----------------------+------+------+------+| @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 |+----------------------+------+------+------+| 5 | 5 | 1 | 4 |+----------------------+------+------+------+

用戶變數可以用於表達式中。目前不包括明顯需要文字值的上下文中,例如SELECT語句的LIMIT子句,或者LOAD DATA語句的IGNORE number LINES子句。

如果使用沒有初始化的變數,其值是NULL。

如果用戶變數分配了一個字元串值,其字符集和校對規則與該字元串的相同。用戶變數的可壓縮性(coercibility)是隱含的。(即為表列值的相同的可壓縮性(coercibility)。

注釋:在SELECT語句中,表達式發送到客戶端後才進行計算。這說明在HAVING、GROUP BY或者ORDER BY子句中,不能使用包含SELECT列表中所設的變數的表達式。例如,下面的語句不能按期望工作:

mysql> SELECT (@aa:=id) AS a,(@aa+3) AS b 從tbl_name HAVING b=5;

HAVING子句中引用了SELECT列表中的表達式的別名,使用@aa。不能按期望工作:@aa不包含當前行的值,而是前面所選的行的id值。

一般原則是不要在語句的一個部分為用戶變數分配一個值而在同一語句的其它部分使用該變數。可能會得到期望的結果,但不能保證。

設置變數並在同一語句中使用它的另一個問題是變數的默認結果的類型取決於語句前面的變數類型。下面的例子說明了該點:

mysql> SET @a=test;mysql> SELECT @a,(@a:=20) FROM tbl_name;

對於該 SELECT語句,MySQL向客戶端報告第1列是一個字元串,並且將@a的所有訪問轉換為字元串,即使@a在第2行中設置為一個數字。執行完SELECT語句後,@a被視為下一語句的一個數字。

要想避免這種問題,要麼不在同一個語句中設置並使用相同的變數,要麼在使用前將變數設置為0、0.0或者以定義其類型。

未分配的變數有一個值NULL,類型為字元串。

9.4. 系統變數

  • 9.4.1. 結構式系統變數

MySQL可以訪問許多系統和連接變數。當伺服器運行時許多變數可以動態更改。這樣通常允許你修改伺服器操作而不需要停止並重啟伺服器。

mysqld伺服器維護兩種變數。全局變數影響伺服器整體操作。會話變數影響具體客戶端連接的操作。

當伺服器啟動時,它將所有全局變數初始化為默認值。這些默認值可以在選項文件中或在命令行中指定的選項進行更改。伺服器啟動後,通過連接伺服器並執行SET GLOBAL var_name語句,可以動態更改這些全局變數。要想更改全局變數,必須具有SUPER許可權。

伺服器還為每個連接的客戶端維護一系列會話變數。在連接時使用相應全局變數的當前值對客戶端的會話變數進行初始化。對於動態會話變數,客戶端可以通過SET

SESSION var_name語句更改它們。設置會話變數不需要特殊許可權,但客戶端只能更改自己的會話變數,而不能更改其它客戶端的會話變數。

對於全局變數的更改可以被訪問該全局變數的任何客戶端看見。然而,它隻影響更改後連接的客戶的從該全局變數初始化的相應會話變數。不影響目前已經連接的客戶端的會話變數(即使客戶端執行SET GLOBAL語句也不影響)。

可以使用幾種語法形式來設置或檢索全局或會話變數。下面的例子使用了sort_buffer_sizeas作為示例變數名。

要想設置一個GLOBAL變數的值,使用下面的語法:

mysql> SET GLOBAL sort_buffer_size=value;mysql> SET @@global.sort_buffer_size=value;

要想設置一個SESSION變數的值,使用下面的語法:

mysql> SET SESSION sort_buffer_size=value;mysql> SET @@session.sort_buffer_size=value;mysql> SET sort_buffer_size=value;

LOCAL是SESSION的同義詞。

如果設置變數時不指定GLOBAL、SESSION或者LOCAL,默認使用SESSION。參見13.5.3節,「SET語法」。

要想檢索一個GLOBAL變數的值,使用下面的語法:

mysql> SELECT @@global.sort_buffer_size;mysql> SHOW GLOBAL VARIABLES like sort_buffer_size;

要想檢索一個SESSION變數的值,使用下面的語法:

mysql> SELECT @@sort_buffer_size;mysql> SELECT @@session.sort_buffer_size;mysql> SHOW SESSION VARIABLES like sort_buffer_size;

這裡,LOCAL也是SESSION的同義詞。

當你用SELECT @@var_name搜索一個變數時(也就是說,不指定global.、session.或者local.),MySQL返回SESSION值(如果存在),否則返回GLOBAL值。

對於SHOW VARIABLES,如果不指定GLOBAL、SESSION或者LOCAL,MySQL返回SESSION值。

當設置GLOBAL變數需要GLOBAL關鍵字但檢索時不需要它們的原因是防止將來出現問題。如果我們移除一個與某個GLOBAL變數具有相同名字的SESSION變數,具有SUPER許可權的客戶可能會意外地更改GLOBAL變數而不是它自己的連接的SESSION變數。如果我們添加一個與某個GLOBAL變數具有相同名字的SESSION變數,想更改GLOBAL變數的客戶可能會發現只有自己的SESSION變數被更改了。

以上技術由重慶思庄提供


推薦閱讀:

有哪些面向數據分析人員的mysql書籍/教程推薦?
MySQL建立關聯表可以不創建主鍵么?

TAG:MySQL | MySQL入门 |