MySQL 5.1参考手册 :: 9.语言结构(2)
时间:2008-05-11 来源:sdccf
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变量被更改了。
关于系统启动选项和系统变量的详细信息参见5.3.1节,“mysqld命令行选项”和5.3.3节,“服务器系统变量”。在5.3.3.1节,“动态系统变量”中列出了可以在运行时设置的变量。
9.4.1. 结构式系统变量
结构式变量在两个方面不同于常规系统变量:
· 其值是一个含组件的结构,可以指定服务器参数,一般紧密相关。
· 可能是给定类型的结构式变量的几个实例。每个实例有一个不同的名,指向服务器维护的不同的资源。
MySQL 5.1支持结构式变量类型,可以指定监控键值缓存操作的参数。键值缓存结构式变量有以下组件:
· key_buffer_size
· key_cache_block_size
· key_cache_division_limit
· key_cache_age_threshold
该节描述了引用结构式变量的语法。在语法的例子中使用了键值缓存变量,但关于键值缓存如何操作的具体详情在其它章节中,如 7.4.6节,“MyISAM键高速缓冲”。
要引用结构式变量实例的组件,可以使用instance_name.component_name格式的复合名。例如:
hot_cache.key_buffer_size
hot_cache.key_cache_block_size
cold_cache.key_cache_block_size
对于每个结构式系统变量,总是预定义名为default的一个实例。如果不使用任何实例名引用结构式变量的一个组件,default实例被使用。这样,default.key_buffer_size和key_buffer_sizeboth均指向同一系统变量。
结构式变量实例和组件的命名规则为:
· 对于给定类型的结构式变量,每个实例必须有一个在该类变量中唯一的一个名。但是,在不同类型的结构式变量中实例名不需要唯一。例如,每个结构式变量有一个实例default,因此在不同的变量类型中default不是唯一的。
· 每个结构式变量类型的组件名在所有系统变量名中必须是唯一的。如果不是这样(也就是说,如果两个不同类型的结构式变量能够共享组件成员名),将不清楚使用哪个默认结构式变量来用作没有使用实例名限定的成员名。
· 如果结构式变量实例名作为未引起来的识别符不合法,将它用反勾号引起来作为识别符。例如,hot-cache不合法,但`hot-cache` 合法。
· global、session和local不是合法实例名。这样可以避免与引用非结构式系统变量的符号的冲突,例如@@global.var_name。
目前,这前两个规则不可能违背,因为唯一的结构式变量类型是键值缓存。在将来创建其它类型的结构式变量,这些规则将有重要的意义。
一个例外是,可以在可能出现简单变量名的上下文中使用复合名引用结构式变量组件。例如,可以使用一个命令行选项未某个结构式变量分配一个值:
shell> mysqld --hot_cache.key_buffer_size=64K
在选项文件中,使用:
[mysqld]
hot_cache.key_buffer_size=64K
如果用该选项启动服务器,除了默认大小为8MB的默认键值缓存,还创建一个名为hot_cache的键值缓存,大小为64KB。
假定你这样启动服务器:
shell> mysqld --key_buffer_size=256K \
--extra_cache.key_buffer_size=128K \
--extra_cache.key_cache_block_size=2048
在这种情况下,服务器将默认键值缓存的大小设定为256KB。(也可以写成--default.key_buffer_size=256K)。 并且,服务器创建一个名为extra_cache的第2个键值缓存,大小为128KB,缓存表索引块的块缓存区的大小设置为2048字节。
在下面的例子中,用3个不同的键值缓存(大小比例为3:1:1)启动服务器:
shell> mysqld --key_buffer_size=6M \
--hot_cache.key_buffer_size=2M \
--cold_cache.key_buffer_size=2M
也可以在运行时设置和检索结构式变量值。例如,要想将名为hot_cache的一个键值缓存的大小设置为10MB,使用下面任何一个语句:
mysql> SET GLOBAL hot_cache.key_buffer_size = 10*1024*1024;
mysql> SET @@global.hot_cache.key_buffer_size = 10*1024*1024;
要想检索缓存大小,执行:
mysql> SELECT @@global.hot_cache.key_buffer_size;
但是,下面的语句不工作。变量不解释为一个复合名,而是解释为LIKE模式匹配操作的简单字符串:
mysql> SHOW GLOBAL VARIABLES LIKE 'hot_cache.key_buffer_size';
这是一个在可能出现简单的变量名时使用结构式变量名的例子。
9.5. 注释语法
MySQL服务器支持3种注释风格:
· 从‘#’字符从行尾。
· 从‘-- ’序列到行尾。请注意‘-- ’(双破折号)注释风格要求第2个破折号后面至少跟一个空格符(例如空格、tab、换行符等等)。该语法与标准SQL注释语法稍有不同,后者将在1.8.5.7, “‘--’作为注释起始标记”中讨论。
· 从/*序列到后面的*/序列。结束序列不一定在同一行中,因此该语法允许注释跨越多行。
下面的例子显示了3种风格的注释:
mysql> SELECT 1+1; # This comment continues to the end of line
mysql> SELECT 1+1; -- This comment continues to the end of line
mysql> SELECT 1 /* this is an in-line comment */ + 1;
mysql> SELECT 1+
/*
this is a
multiple-line comment
*/
1;
上述的注释语法适用于mysqld服务器如何分析SQL语句。发送到服务器之前,mysql客户程序也执行部分语句解析。(例如,它通过解析来确定在多语句行中的语句边界)。
在MySQL 5.1中,mysql解析/* ...*/注释的唯一局限性是结合该风格的注释定界符使用的叹号标记了有条件执行的SQL语句部分。适用于交互式运行mysql和将命令放入一个文件中,并以批处理模式使用mysql来处理mysql < file_name的文件。详细信息和例子参见1.8.4节,“MySQL对标准SQL的扩展”。
9.6. MySQL中保留字的处理
尝试使用一个识别符,例如使用嵌入式MySQL数据类型或函数名作为表名或列名,例如TIMESTAMP或GROUP,会造成一个常见问题。允许你这样操作(例如,ABS可以作为一个列名)。但是,默认情况下,在数调用中在函数名和后面的‘(’字符之间不允许有空格。该要求使函数调用与列名引用不同。
该行为的不利结果是在某些上下文中省略一个空格会使识别符解释为函数名。例如,该语句合法:
mysql> CREATE TABLE abs (val INT);
但省略abs后面的空格会造成语法错误,因为省略后该语句好像要调用ABS()函数:
mysql> CREATE TABLE abs(val INT);
如果SQL服务器模式包括IGNORE_SPACE模式值,服务器允许函数调用时在函数名和后面的‘(’字符之间有空格。这样使函数名被视为保留字。结果是,与函数名相同的识别符必须按照9.2节,“数据库、表、索引、列和别名”中所描述的引起来。SQL服务器模式按照5.3.2节,“SQL服务器模式”中所描述的进行控制。
限定名中句点后面的字必须为一个识别符,因此不需要将它引起来,即使它是一个保留字。
在MySQL中,下表中的字显式被保留。其中大多数字进制被标准SQL用作列名和/或表名(例如,GROUP)。少数被保留了,因为MySQL需要它们,(目前)使用yacc解析程序。保留字被引起来后可以用作识别符。
ADD | ALL | ALTER |
ANALYZE | AND | AS |
ASC | ASENSITIVE | BEFORE |
BETWEEN | BIGINT | BINARY |
BLOB | BOTH | BY |
CALL | CASCADE | CASE |
CHANGE | CHAR | CHARACTER |
CHECK | COLLATE | COLUMN |
CONDITION | CONNECTION | CONSTRAINT |
CONTINUE | CONVERT | CREATE |
CROSS | CURRENT_DATE | CURRENT_TIME |
CURRENT_TIMESTAMP | CURRENT_USER | CURSOR |
DATABASE | DATABASES | DAY_HOUR |
DAY_MICROSECOND | DAY_MINUTE | DAY_SECOND |
DEC | DECIMAL | DECLARE |
DEFAULT | DELAYED | DELETE |
DESC | DESCRIBE | DETERMINISTIC |
DISTINCT | DISTINCTROW | DIV |
DOUBLE | DROP | DUAL |
EACH | ELSE | ELSEIF |
ENCLOSED | ESCAPED | EXISTS |
EXIT | EXPLAIN | FALSE |
FETCH | FLOAT | FLOAT4 |
FLOAT8 | FOR | FORCE |
FOREIGN | FROM | FULLTEXT |
GOTO | GRANT | GROUP |
HAVING | HIGH_PRIORITY | HOUR_MICROSECOND |
HOUR_MINUTE | HOUR_SECOND | IF |
IGNORE | IN | INDEX |
INFILE | INNER | INOUT |
INSENSITIVE | INSERT | INT |
INT1 | INT2 | INT3 |
INT4 | INT8 | INTEGER |
INTERVAL | INTO | IS |
ITERATE | JOIN | KEY |
KEYS | KILL | LABEL |
LEADING | LEAVE | LEFT |
LIKE | LIMIT | LINEAR |
LINES | LOAD | LOCALTIME |
LOCALTIMESTAMP | LOCK | LONG |
LONGBLOB | LONGTEXT | LOOP |
LOW_PRIORITY | MATCH | MEDIUMBLOB |
MEDIUMINT | MEDIUMTEXT | MIDDLEINT |
MINUTE_MICROSECOND | MINUTE_SECOND | MOD |
MODIFIES | NATURAL | NOT |
NO_WRITE_TO_BINLOG | NULL | NUMERIC |
ON | OPTIMIZE | OPTION |
OPTIONALLY | OR | ORDER |
OUT | OUTER | OUTFILE |
PRECISION | PRIMARY | PROCEDURE |
PURGE | RAID0 | RANGE |
READ | READS | REAL |
REFERENCES | REGEXP | RELEASE |
RENAME | REPEAT | REPLACE |
REQUIRE | RESTRICT | RETURN |
REVOKE | RIGHT | RLIKE |
SCHEMA | SCHEMAS | SECOND_MICROSECOND |
SELECT | SENSITIVE | SEPARATOR |
SET | SHOW | SMALLINT |
SPATIAL | SPECIFIC | SQL |
SQLEXCEPTION | SQLSTATE | SQLWARNING |
SQL_BIG_RESULT | SQL_CALC_FOUND_ROWS | SQL_SMALL_RESULT |
SSL | STARTING | STRAIGHT_JOIN |
TABLE | TERMINATED | THEN |
TINYBLOB | TINYINT | TINYTEXT |
TO | TRAILING | TRIGGER |
TRUE | UNDO | UNION |
UNIQUE | UNLOCK | UNSIGNED |
UPDATE | USAGE | USE |
USING | UTC_DATE | UTC_TIME |
UTC_TIMESTAMP | VALUES | VARBINARY |
VARCHAR | VARCHARACTER | VARYING |
WHEN | WHERE | WHILE |
WITH | WRITE | X509 |
XOR | YEAR_MONTH | ZEROFILL |
MySQL允许部分关键字用做未引起来的识别符,因为许多人以前曾使用过它们。下面列出了一些例子:
-
ACTION
-
BIT
-
DATE
-
ENUM
-
NO
-
TEXT
-
TIME
-
TIMESTAMP
这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访问dev.mysql.com.。原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的。