目录
本章讨论 使用MySQL时 编写以下 SQL 语句 元素的规则 :
字符串和数字等字面值
标识符,例如数据库,表和列名称
关键词和保留词
用户定义的和系统变量
评论
本节介绍如何在MySQL中编写文字值。
这些包括字符串,数字,十六进制和位值,布尔值和
NULL
。
本节还介绍了在MySQL中处理这些基本类型时可能遇到的各种细微差别。
字符串是一个字节或字符序列,包含在单引号(
'
)或双引号(
"
)字符中。
例子:
'一个字符串' “另一个字符串”
彼此相邻的带引号的字符串连接成一个字符串。 以下行是等效的:
'一个字符串' 'a'''''字符串'
如果
ANSI_QUOTES
启用
了
SQL模式,则只能在单引号内引用字符串文字,因为在双引号内引用的字符串将被解释为标识符。
甲
二进制串
是一个字节的字符串。
每个二进制字符串都有一个字符集和排序规则
binary
。
一个
非二进制字符串
是字符的字符串。
它具有除字符集以外的字符集
binary
和与字符集兼容的排序规则。
对于这两种类型的字符串,比较基于字符串单元的数值。 对于二进制字符串,单位是字节; 比较使用数字字节值。 对于非二进制字符串,单位是字符,一些字符集支持多字节字符; 比较使用数字字符代码值。 字符代码排序是字符串排序规则的一个功能。 (有关更多信息,请参见 第10.8.5节“二进制排序与_bin排序相比” 。)
字符串文字可以具有可选的字符集介绍人和
COLLATE
子句,以将其指定为使用特定字符集和排序规则的字符串:
[_charset_name
]'string
'[收集collation_name
]
例子:
SELECT _latin1'string
'; SELECT _binary'string
'; SELECT _utf8''COLLATEstring
utf8_danish_ci;
您可以使用
(或
)在国家字符集中创建字符串。
这些陈述是等价的:
N'
literal
'n'
literal
'
SELECT N'some text'; SELECT n'some text'; SELECT _utf8的一些文字';
有关这些形式的字符串语法的信息,请参见 第10.3.7节“国家字符集” 和 第10.3.8节“字符集介绍” 。
在字符串中,除非
NO_BACKSLASH_ESCAPES
启用SQL模式,
否则某些序列具有特殊含义
。
这些序列中的每一个都以反斜杠(
\
)
开头
,称为
转义字符
。
MySQL识别
表9.1“特殊字符转义序列”中显示的转义序列
。
对于所有其他转义序列,将忽略反斜杠。
也就是说,转义字符被解释为好像它没有被转义。
例如,
\x
就是这样
x
。
这些序列区分大小写。
例如,
\b
被解释为退格,但
\B
被解释为
B
。
根据
character_set_connection
系统变量
指示的字符集完成转义处理
。
即使对于前导有指示不同字符集的介绍人的字符串也是如此,如
第10.3.6节“字符串文字字符集和排序规则”中所述
。
ASCII 26字符可以编码为
\Z
使您能够解决ASCII 26代表Windows上的END-OF-FILE的问题。
如果您尝试使用,文件中的ASCII 26会导致问题
。
mysql
db_name
<
file_name
的
\%
和
\_
序列用于搜索的文字实例
%
和
_
其中它们否则会被解释为通配符在模式匹配上下文。
请参见
第12.5.1节“字符串比较函数”
中的
LIKE
运算符
说明
。
如果您使用
或
模式匹配上下文之外,他们评估的字符串
和
,不
和
。
\%
\_
\%
\_
%
_
有几种方法可以在字符串中包含引号字符:
一个
'
带引号的字符串中
'
可以写成
''
。
一个
"
带引号的字符串中
"
可以写成
""
。
通过转义字符(
\
)来
引用引号字符
。
一个
'
带引号的字符串内
"
不需要特殊对待而且不必增加一倍或逃脱。
以同样的方式,
"
引用的字符串里面
'
不需要特殊处理。
以下
SELECT
语句演示了引用和转义的工作原理:
MySQL的>SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+ ------- + --------- + ----------- + -------- + -------- + | 你好| “你好”| “”你好“”| hel'lo | '你好| + ------- + --------- + ----------- + -------- + -------- + MySQL的>SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+ ------- + --------- + ----------- + -------- + -------- + | 你好| '你好'| ''你好''| hel“lo |”你好| + ------- + --------- + ----------- + -------- + -------- + MySQL的>SELECT 'This\nIs\nFour\nLines';
+ -------------------- + | 这个 是 四 线条| + -------------------- + MySQL的>SELECT 'disappearing\ backslash';
+ ------------------------ + | 消失的反斜杠| + ------------------------ +
要将二进制数据插入字符串列(例如
BLOB
列),您应该通过转义序列表示某些字符。
\
必须转义
反斜杠(
)和用于引用字符串的引号字符。
在某些客户端环境中,可能还需要转义
NUL
或Control + Z.
在
MySQL的
客户端会截断引号包含字符串的
NUL
字符,如果他们没能逃脱,并控制+ Z,可以采取档案结尾在Windows上,如果没有逃脱。
有关表示每个字符的转义序列,请
参见表9.1“特殊字符转义序列”
。
编写应用程序时,在将字符串用作发送到MySQL服务器的SQL语句中的数据值之前,必须正确转义任何可能包含这些特殊字符的字符串。 您可以通过两种方式执行此操作:
使用转义特殊字符的函数处理字符串。
在C程序中,您可以使用
mysql_real_escape_string_quote()
C API函数来转义字符。
请参见
第28.7.7.56节“mysql_real_escape_string_quote()”
。
在构造其他SQL语句的SQL语句中,您可以使用该
QUOTE()
函数。
Perl DBI接口提供了
quote
一种将特殊字符转换为正确转义序列的方法。
请参见
第28.9节“MySQL Perl API”
。
其他语言接口可以提供类似的功能。
作为显式转义特殊字符的替代方法,许多MySQL API提供占位符功能,使您能够将特殊标记插入到语句字符串中,然后在发出语句时将数据值绑定到它们。 在这种情况下,API负责为您转义值中的特殊字符。
数字文字包括精确值(整数和
DECIMAL
)文字和近似值(浮点)文字。
整数表示为数字序列。
数字可以包括
.
小数分隔符。
数字可以分别在前面
-
或
+
表示负值或正值。
用尾数和指数以科学记数法表示的数字是近似值数字。
精确值数字文字具有整数部分或小数部分,或两者都有。
他们可能会签名。
例如:
1
,
.2
,
3.4
,
-5
,
-6.78
,
+9.10
。
近似值数字文字用科学记数法表示,带有尾数和指数。
可以签署任一部分或两部分。
例如:
1.2E3
,
1.2E-3
,
-1.2E3
,
-1.2E-3
。
两个看起来相似的数字可能会有不同的对待。
例如,
2.34
是精确值(定点)数,而是
2.34E0
近似值(浮点数)。
的
DECIMAL
数据类型是一个定点类型和计算是精确的。
在MySQL中,
DECIMAL
类型有多个同义词:
NUMERIC
,
DEC
,
FIXED
。
整数类型也是精确值类型。
有关精确值计算的更多信息,请参见
第12.25节“精确数学”
。
该
FLOAT
和
DOUBLE
数据类型是浮点类型,其计算是近似的。
在MySQL中,类型与同义
FLOAT
或
DOUBLE
有
DOUBLE PRECISION
和
REAL
。
整数可以用在浮点上下文中; 它被解释为等效的浮点数。
日期和时间值可以用多种格式表示,例如带引号的字符串或数字,具体取决于值的确切类型和其他因素。
例如,在上下文中,其中的MySQL预计日期时,它解释任何的
'2015-07-21'
,
'20150721'
以及
20150721
作为一个日期。
本节介绍日期和时间文字的可接受格式。 有关时态数据类型的更多信息,例如允许值的范围,请参阅以下部分:
标准SQL和ODBC日期和时间字面值。 标准SQL允许使用类型关键字和字符串指定时态文字。 关键字和字符串之间的空格是可选的。
日期'str
' 时间'str
' TIMESTAMP'str
'
MySQL识别这些构造以及相应的ODBC语法:
{d'str
'} {t'str
'} {ts'str
'}
MySQL使用type关键字,这些结构分别产生
DATE
,
TIME
和
DATETIME
值,如果指定则包括尾部小数秒部分。
该
TIMESTAMP
语法产生
DATETIME
在MySQL的价值,因为
DATETIME
有更紧密地对应于标准SQL的范围
TIMESTAMP
类型,其中有一年范围
0001
到
9999
。
(MySQL的
TIMESTAMP
年份范围是
1970
到
2038
。)
日期和时间上下文中的字符串和数字文字。
MySQL
DATE
以这些格式
识别
值:
作为字母
'YYYY-MM-DD'
或
'YY-MM-DD'
格式
的字符串
。
允许
使用
“
宽松
”
语法:任何标点符号都可以用作日期部分之间的分隔符。
例如,
'2012-12-31'
,
'2012/12/31'
,
'2012^12^31'
,和
'2012@12@31'
是相等的。
作为字符串中没有分隔符
'YYYYMMDD'
或
'YYMMDD'
格式的字符串,前提是该字符串作为日期有意义。
例如,
'20070523'
并且
'070523'
被解释为
'2007-05-23'
,但是
'071332'
非法(它具有无意义的月和日部分)并且变为
'0000-00-00'
。
作为数字
YYYYMMDD
或
YYMMDD
格式的数字,只要该数字作为日期有意义。
例如,
19830905
并被
830905
解释为
'1983-09-05'
。
MySQL
以这些格式
识别
DATETIME
和
TIMESTAMP
评估:
作为字母
'YYYY-MM-DD
hh:mm:ss'
或
'YY-MM-DD
hh:mm:ss'
格式
的字符串
。
这里也允许
使用
“
宽松
”
语法:任何标点符号都可以用作日期部分或时间部分之间的分隔符。
例如,
'2012-12-31 11:30:45'
,
'2012^12^31 11+30+45'
,
'2012/12/31 11*30*45'
,和
'2012@12@31 11^30^45'
是相等的。
在日期和时间部分与小数秒部分之间识别的唯一分隔符是小数点。
日期和时间部分可以由
T
空格
分隔
而不是空格。
例如,
'2012-12-31 11:30:45'
'2012-12-31T11:30:45'
是等价的。
作为字符串中没有分隔符
'YYYYMMDDhhmmss'
或
'YYMMDDhhmmss'
格式的字符串,前提是该字符串作为日期有意义。
例如,
'20070523091528'
并且
'070523091528'
被解释为
'2007-05-23 09:15:28'
,但是
'071122129015'
非法(它具有无意义的微小部分)并且变为
'0000-00-00
00:00:00'
。
作为数字
YYYYMMDDhhmmss
或
YYMMDDhhmmss
格式的数字,只要该数字作为日期有意义。
例如,
19830905132800
并被
830905132800
解释为
'1983-09-05 13:28:00'
。
A
DATETIME
或
TIMESTAMP
值可以包括高达微秒(6位)精度的尾随小数秒部分。
小数部分应始终与其余时间分开一个小数点;
没有识别出其他小数秒分隔符。
有关MySQL
中小
数秒支持的信息,请参见
第11.3.5节“时间值中的
小数秒
”
。
包含两位数年份值的日期不明确,因为这个世纪是未知的。 MySQL使用以下规则解释两位数的年份值:
范围
70-99
中的
年份值
将转换为
1970-1999
。
范围
00-69
中的
年份值
将转换为
2000-2069
。
另见 第11.3.7节“日期中的两位数年份” 。
对于指定为包含日期部分分隔符的字符串的值,不必为小于的月份或日期值指定两个数字
10
。
'2015-6-9'
是一样的
'2015-06-09'
。
同样,对于指定为包含时间部分分隔符的字符串的值,不必为小于的小时,分钟或秒值指定两个数字
10
。
'2015-10-30
1:2:3'
是一样的
'2015-10-30
01:02:03'
。
指定为数字的值应为6,8,12或14位长。
如果一个数字是8或14位长,则假定它是
格式
YYYYMMDD
或
YYYYMMDDhhmmss
格式,并且年份由前4位数给出。
如果数字长度为6或12位,则假定为
格式
YYMMDD
或
YYMMDDhhmmss
格式,并且年份由前2位数给出。
不是这些长度之一的数字被解释为用前导零填充到最接近的长度。
指定为非定界字符串的值将根据其长度进行解释。
对于长度为8或14个字符的字符串,假定年份由前4个字符给出。
否则,假定年份由前2个字符给出。
字符串从左到右解释,以查找字符串中存在的多个部分的年,月,日,小时,分钟和秒值。
这意味着您不应使用少于6个字符的字符串。
例如,如果您指定
'9903'
,表示代表1999年3月,则MySQL将其转换为
“
零
”
日期值。
发生这种情况是因为年和月的值是
99
和
03
,但是那一天完全没有了。
但是,您可以明确指定零值以表示缺少的月份或日期部分。
例如,要插入值
'1999-03-00'
,请使用
'990300'
。
MySQL
TIME
以这些格式
识别
值:
作为
'D hh:mm:ss'
格式
的字符串
。
您也可以使用以下的一个
“
宽松
”
的语法:
'hh:mm:ss'
,
'hh:mm'
,
'D
hh:mm'
,
'D hh'
,或
'ss'
。
这里
D
代表天数,可以有0到34之间的值。
作为一个没有
'hhmmss'
格式
分隔符的字符串
,只要它在时间上有意义。
例如,
'101112'
被理解为
'10:11:12'
,但是
'109712'
非法(它有一个荒谬的微小部分)并且变成
'00:00:00'
。
作为
hhmmss
格式中
的数字
,只要它作为时间有意义。
例如,
101112
被理解为
'10:11:12'
。
以下备选格式也理解:
ss
,
mmss
,或
hhmmss
。
结尾的部分的秒部分在所识别的
'D hh:mm:ss.fraction'
,
'hh:mm:ss.fraction'
,
'hhmmss.fraction'
,和
hhmmss.fraction
时间的格式,其中,
fraction
是在高达微秒(6位)精度的小数部分。
小数部分应始终与其余时间分开一个小数点;
没有识别出其他小数秒分隔符。
有关MySQL
中小
数秒支持的信息,请参见
第11.3.5节“时间值中的
小数秒
”
。
对于
TIME
指定为包含时间部件分隔符的字符串的值,不必为小于,小时或秒的值指定两个数字
10
。
'8:3:2'
是一样的
'08:03:02'
。
十六进制文字值使用
或
表示法
编写
,其中
包含十六进制数字(
,
)。
数字和任何领先的字母
都没关系。
前导
区分大小写,不能写为
。
X'
val
'0x
val
val
0..9
A..F
X
0x
0X
合法的十六进制文字:
X'01AF” X'01af” x'01AF” x'01af” 0x01AF 0x01af
非法十六进制文字:
X'0G'(G不是十六进制数字) 0X01AF(0X必须写为0x)
使用
表示法
写入的值
必须包含偶数位数或发生语法错误。
要更正此问题,请使用前导零填充值:
X'
val
'
MySQL的>SET @s = X'FFF';
错误1064(42000):您的SQL语法有错误; 查看与MySQL服务器对应的手册 在“X'FFF”附近使用正确语法的版本 MySQL的>SET @s = X'0FFF';
查询正常,0行受影响(0.00秒)
使用
包含奇数位数的符号
写入的值
被视为具有额外的前导
。
例如,
被解释为
。
0x
val
0
0xaaa
0x0aaa
默认情况下,十六进制文字是二进制字符串,其中每对十六进制数字代表一个字符:
MySQL的>SELECT X'4D7953514C', CHARSET(X'4D7953514C');
+ --------------- + ------------------------ + | X'4D7953514C'| CHARSET(X'4D7953514C')| + --------------- + ------------------------ + | MySQL | 二进制| + --------------- + ------------------------ + MySQL的>SELECT 0x5461626c65, CHARSET(0x5461626c65);
+ -------------- + ----------------------- + | 0x5461626c65 | CHARSET(0x5461626c65)| + -------------- + ----------------------- + | 表| 二进制| + -------------- + ----------------------- +
十六进制文字可以具有可选的字符集介绍者和
COLLATE
子句,以将其指定为使用特定字符集和排序规则的字符串:
[_charset_name
] X'val
'[COLLATEcollation_name
]
例子:
SELECT _latin1 X'4D7953514C'; SELECT _utf8 0x4D7953514C COLLATE utf8_danish_ci;
这些示例使用
符号,但
符号也允许引入者。
有关介绍人的信息,请参见
第10.3.8节“字符集介绍人”
。
X'
val
'0x
val
在数字上下文中,MySQL将十六进制文字视为
BIGINT
(64位整数)。
要确保对十六进制文字进行数字处理,请在数字上下文中使用它。
这样做的方法包括添加0或使用
CAST(... AS UNSIGNED)
。
例如,默认情况下,分配给用户定义变量的十六进制文字是二进制字符串。
要将值指定为数字,请在数字上下文中使用它:
mysql>SET @v1 = X'41';
mysql>SET @v2 = X'41'+0;
mysql>SET @v3 = CAST(X'41' AS UNSIGNED);
mysql>SELECT @v1, @v2, @v3;
+ ------ + ------ + ------ + | @ v1 | @ v2 | @ v3 | + ------ + ------ + ------ + | A | 65 | 65 | + ------ + ------ + ------ +
空十六进制值(
X''
)计算为零长度二进制字符串。
转换为数字,它产生0:
MySQL的>SELECT CHARSET(X''), LENGTH(X'');
+ -------------- + ------------- + | CHARSET(X'')| 长度(X'')| + -------------- + ------------- + | 二进制| 0 | + -------------- + ------------- + MySQL的>SELECT X''+0;
+ ------- + | X''+ 0 | + ------- + | 0 | + ------- +
该
表示法基于标准SQL。
该
表示法基于ODBC,其十六进制字符串通常用于为
列
提供值
。
X'
val
'0x
BLOB
要将字符串或数字转换为十六进制格式的字符串,请使用以下
HEX()
函数:
MySQL的>SELECT HEX('cat');
+ ------------ + | 十六进制('猫')| + ------------ + | 636174 | + ------------ + MySQL的>SELECT X'636174';
+ ----------- + | X'636174'| + ----------- + | 猫| + ----------- +
对于十六进制文字,位操作被视为数字上下文,但位操作允许MySQL 8.0及更高版本中的数字或二进制字符串参数。
要显式指定十六进制文字的二进制字符串上下文,请使用
_binary
至少一个参数
的
介绍人:
mysql>SET @v1 = X'000D' | X'0BC0';
mysql>SET @v2 = _binary X'000D' | X'0BC0';
mysql>SELECT HEX(@v1), HEX(@v2);
+ ---------- + ---------- + | 十六进制(@ v1)| HEX(@ v2)| + ---------- + ---------- + | BCD | 0BCD | + ---------- + ---------- +
所显示的结果,这样对位操作类似,但没有结果
_binary
是一个
BIGINT
值,而将结果与
_binary
一个二进制字符串。
由于结果类型不同,显示的值不同:数字结果不显示高位0位数。
位值文字是使用
或
表示法
编写的
。
是使用零和1写的二进制值。
任何领导的信件
都没关系。
前导
区分大小写,不能写为
。
b'
val
'0b
val
val
b
0b
0B
合法的比特值文字:
B'01' B'01' 0B01
非法位值文字:
b'2'(2不是二进制数字) 0B01(0B必须写为0b)
默认情况下,位值文字是二进制字符串:
MySQL的>SELECT b'1000001', CHARSET(b'1000001');
+ ------------ + --------------------- + | b'1000001'| CHARSET(b'1000001')| + ------------ + --------------------- + | A | 二进制| + ------------ + --------------------- + MySQL的>SELECT 0b1100001, CHARSET(0b1100001);
+ ----------- + -------------------- + | 0b1100001 | CHARSET(0b1100001)| + ----------- + -------------------- + | a | 二进制| + ----------- + -------------------- +
位值文字可以具有可选的字符集介绍者和
COLLATE
子句,以将其指定为使用特定字符集和排序规则的字符串:
[_charset_name
] b'val
'[COLLATEcollation_name
]
例子:
SELECT _latin1 b'1000001'; SELECT _utf8 0b1000001 COLLATE utf8_danish_ci;
这些示例使用
符号,但
符号也允许引入者。
有关介绍人的信息,请参见
第10.3.8节“字符集介绍人”
。
b'
val
'0b
val
在数字上下文中,MySQL将字面视为整数。
要确保对位字面值进行数字处理,请在数字上下文中使用它。
这样做的方法包括添加0或使用
CAST(... AS UNSIGNED)
。
例如,默认情况下,分配给用户定义变量的位文字是二进制字符串。
要将值指定为数字,请在数字上下文中使用它:
mysql>SET @v1 = b'1100001';
mysql>SET @v2 = b'1100001'+0;
mysql>SET @v3 = CAST(b'1100001' AS UNSIGNED);
mysql>SELECT @v1, @v2, @v3;
+ ------ + ------ + ------ + | @ v1 | @ v2 | @ v3 | + ------ + ------ + ------ + | a | 97 | 97 | + ------ + ------ + ------ +
空位值(
b''
)计算为零长度二进制字符串。
转换为数字,它产生0:
MySQL的>SELECT CHARSET(b''), LENGTH(b'');
+ -------------- + ------------- + | CHARSET(b'')| 长度(b'')| + -------------- + ------------- + | 二进制| 0 | + -------------- + ------------- + MySQL的>SELECT b''+0;
+ ------- + | b''+ 0 | + ------- + | 0 | + ------- +
位值表示法便于指定要分配给
BIT
列的
值
:
mysql>CREATE TABLE t (b BIT(8));
mysql>INSERT INTO t SET b = b'11111111';
mysql>INSERT INTO t SET b = b'1010';
mysql>INSERT INTO t SET b = b'0101';
结果集中的位值将作为二进制值返回,这可能无法很好地显示。
要将位值转换为可打印格式,请在数字上下文中使用它或使用转换函数(如
BIN()
或)
HEX()
。
转换后的值中不显示高位0位数。
MySQL的> SELECT b+0, BIN(b), OCT(b), HEX(b) FROM t;
+ ------ + ---------- + -------- + -------- +
| b + 0 | BIN(b)| OCT(b)| HEX(b)|
+ ------ + ---------- + -------- + -------- +
| 255 | 11111111 | 377 | FF |
| 10 | 1010 | 12 | A |
| 5 | 101 | 5 | 5 |
+ ------ + ---------- + -------- + -------- +
对于位文字,位操作被视为数字上下文,但位操作允许MySQL 8.0及更高版本中的数字或二进制字符串参数。
要为位文字显式指定二进制字符串上下文,请使用
_binary
至少一个参数
的
介绍人:
mysql>SET @v1 = b'000010101' | b'000101010';
mysql>SET @v2 = _binary b'000010101' | _binary b'000101010';
mysql>SELECT HEX(@v1), HEX(@v2);
+ ---------- + ---------- + | 十六进制(@ v1)| HEX(@ v2)| + ---------- + ---------- + | 3F | 003F | + ---------- + ---------- +
所显示的结果,这样对位操作类似,但没有结果
_binary
是一个
BIGINT
值,而将结果与
_binary
一个二进制字符串。
由于结果类型不同,显示的值不同:数字结果不显示高位0位数。
该
NULL
值意味着
“
没有数据。
“
NULL
可以用任何字母写成。
请注意,该
NULL
值与
0
数值类型或字符串类型的空字符串
等值不同
。
有关更多信息,请参见
第B.4.4.3节“NULL值的问题”
。
对于使用
LOAD
DATA
or
执行的文本文件导入或导出操作
SELECT
... INTO
OUTFILE
,
NULL
由
\N
序列
表示
。
请参见
第13.2.7节“LOAD DATA语法”
。
对于排序方式
ORDER BY
,
NULL
值在升序排序的其他值之前排序,在降序排序的其他值之后排序。
MySQL中的某些对象(包括数据库,表,索引,列,别名,视图,存储过程,分区,表空间,资源组和其他对象名称)称为标识符。 本节介绍MySQL中标识符的允许语法。 第9.2.2节“标识符区分大小写” 描述了哪些类型的标识符区分大小写以及在何种条件下。
可以引用或不引用标识符。 如果标识符包含特殊字符或是保留字,则 必须在 引用时引用它。 (例外:在限定名称中的句点之后的保留字必须是标识符,因此不需要引用。)保留字在 第9.3节“关键字和保留字” 中列出 。
标识符在内部转换为Unicode。 它们可能包含以下字符:
不带引号的标识符中允许的字符:
ASCII:[0-9,az,AZ $ _](基本拉丁字母,数字0-9,美元,下划线)
扩展:U + 0080 .. U + FFFF
带引号的标识符中允许的字符包括完整的Unicode基本多语言平面(BMP),但U + 0000除外:
ASCII:U + 0001 .. U + 007F
扩展:U + 0080 .. U + FFFF
引号或非引号标识符中不允许使用ASCII NUL(U + 0000)和补充字符(U + 10000和更高)。
标识符可以以数字开头,但除非引用可能不仅仅由数字组成。
数据库,表和列名称不能以空格字符结尾。
标识符引号字符是反引号(
`
):
MySQL的> SELECT * FROM `select` WHERE `select`.id > 100;
如果
ANSI_QUOTES
启用
了
SQL模式,则还允许在双引号内引用标识符:
MySQL的>CREATE TABLE "test" (col INT);
错误1064:您的SQL语法有错误... mysql>SET sql_mode='ANSI_QUOTES';
mysql>CREATE TABLE "test" (col INT);
查询正常,0行受影响(0.00秒)
该
ANSI_QUOTES
模式使服务器将双引号字符串解释为标识符。
因此,启用此模式时,字符串文字必须包含在单引号内。
它们不能用双引号括起来。
服务器SQL模式的控制如
第5.1.11节“服务器SQL模式”中所述
。
如果引用标识符,标识符引号字符可以包含在标识符中。
如果要包含在标识符中的字符与用于引用标识符本身的字符相同,则需要将该字符加倍。
以下语句创建一个名为的表
a`b
,其中包含一个名为的列
c"d
:
MySQL的> CREATE TABLE `a``b` (`c"d` INT);
在查询的选择列表中,可以使用标识符或字符串引用字符指定带引号的列别名:
MySQL的> SELECT 1 AS `one`, 2 AS 'two';
+ ----- + ----- +
| 一个| 两个|
+ ----- + ----- +
| 1 | 2 |
+ ----- + ----- +
在语句的其他地方,对别名的引用引用必须使用标识符引用,或者引用被视为字符串文字。
建议您不要使用以
或
,where
和
整数
开头的名称
。
例如,避免使用
作为标识符,因为表达式
是不明确的。
根据上下文,它可能被解释为表达式
或数字
。
M
eM
eN
M
N
1e
1e+3
1e
+ 3
1e+3
MD5()
用于生成表名
时要小心,
因为它可能会生成非法或模糊格式的名称,例如刚才描述的名称。
用户变量不能直接在SQL语句中用作标识符或标识符的一部分。 有关 变通方法的更多信息和示例, 请参见 第9.4节“用户定义的变量” 。
数据库和表名中的特殊字符编码在相应的文件系统名称中,如 第9.2.3节“标识符到文件名的映射”中所述 。
下表描述了每种标识符的最大长度。
标识符类型 | 最大长度(字符) |
---|---|
数据库 |
64(
NDB
存储引擎:63)
|
表 |
64(
NDB
存储引擎:63)
|
柱 | 64 |
指数 | 64 |
约束 | 64 |
存储程序 | 64 |
视图 | 64 |
表空间 | 64 |
服务器 | 64 |
日志文件组 | 64 |
别号 | 256(见下表中的例外情况) |
复合声明标签 | 16 |
用户定义的变量 | 64 |
资源组 | 64 |
CREATE
VIEW
将检查语句中
列名的别名,
最大列长度为64个字符(不是最大别名长度为256个字符)。
标识符使用Unicode(UTF-8)存储。
这适用于表定义中的标识符以及存储在
mysql
数据库
中的授权表中的
标识符。
授权表中标识符字符串列的大小以字符为单位。
您可以使用多字节字符,而不会减少存储在这些列中的值所允许的字符数。
如前所述,允许的Unicode字符是基本多语言平面(BMP)中的字符。
不允许使用补充字符。
对于数据库和表的名称,NDB Cluster最大长度为63个字符。 请参见 第22.1.7.5节“与NDB集群中的数据库对象关联的限制” 。
对象名称可能不合格或合格。 在名称解释明确无误的情况下,允许使用非限定名称。 限定名称包括至少一个限定符,以通过覆盖默认上下文或提供缺少的上下文来阐明解释上下文。
例如,此语句使用非限定名称创建表
t1
:
CREATE TABLE t1(i INT);
由于不
t1
包含用于指定数据库的限定符,因此该语句将在默认数据库中创建表。
如果没有默认数据库,则会发生错误。
此语句使用限定名称创建表
db1.t1
:
CREATE TABLE db1.t1(i INT);
因为
db1.t1
包含数据库限定符
db1
,所以语句
t1
在名为的数据库中
创建
db1
,而不管缺省数据库。
如果没有默认数据库,则
必须
指定
限定符
。
如果存在默认数据库,
则
可以指定
限定符
,指定与默认数据库不同的数据库;如果默认值与指定的默认值相同,则可以指定数据库显式。
限定符具有以下特征:
非限定名称由单个标识符组成。 限定名称由多个标识符组成。
多部分名称的组件必须用句点(
.
)字符
分隔
。
多部分名称的初始部分充当限定符,这些限定符影响解释最终标识符的上下文。
限定符字符是单独的标记,不需要与关联的标识符连续。
例如,
tbl_name.col_name
并且
tbl_name . col_name
是等价的。
如果多部分名称的任何组件需要引用,请单独引用它们,而不是引用整个名称。
例如,写
`my-table`.`my-column`
,不
`my-table.my-column`
。
在限定名称中的句点后面的保留字必须是标识符,因此在该上下文中不需要引用它。
对象名称的允许限定符取决于对象类型:
数据库名称是完全限定的,不带限定符:
CREATE DATABASE db1;
可以为表,视图或存储的程序名称指定数据库名称限定符。
CREATE
语句
中不合格和限定名称的示例
:
CREATE TABLE mytable ...; 创造观点... ...; CREATE PROCEDURE myproc ...; 创造功能myfunc ...; 创造事件myevent ......; CREATE TABLE mydb.mytable ...; 创建视图mydb.myview ...; 创建程序mydb.myproc ......; 创建功能mydb.myfunc ...; 创建事件mydb.myevent ...;
触发器与表关联,因此任何限定符都适用于表名:
创造触发mytrigger ...在mytable上......; CREATE TRIGGER mytrigger ...在mydb.mytable ...;
可以为列名提供多个限定符,以指示引用它的语句中的上下文,如下表所示。
列参考 | 含义 |
---|---|
col_name |
列
col_name
从语句中使用哪个表包含名称的列
|
tbl_name.col_name |
默认数据库
col_name
表
tbl_name
中的
列
|
db_name.tbl_name.col_name |
数据库
col_name
表
tbl_name
中的
列
db_name
|
换句话说,可以为列名提供表名限定符,该表限定符本身可以被赋予数据库名限定符。
SELECT
语句中
的非限定和限定列引用的示例
:
从mytable中选择c1 在哪里c2> 100; 选择mytable.c1 FROM mytable 在哪里mytable.c2> 100; SELECT mydb.mytable.c1 FROM mydb.mytable 在哪里mydb.mytable.c2> 100;
除非非限定引用不明确,否则无需在语句中为对象引用指定限定符。
假设列
c1
只在表中出现
t1
,
c2
只在
t2
和
c
两
t1
和
t2
。
任何非限定引用
c
在引用两个表的语句中都是不明确的,必须限定为
t1.c
或
t2.c
表示您的表:
SELECT c1,c2,t1.c FROM t1 INNER JOIN t2 在哪里t2.c> 100;
同样,要从
t
数据库中
的表
db1
和
同一语句
t
中的数据库
db2
中的
表
中检索
,必须限定表引用:对于这些表中的列的引用,仅对两个表中出现的列名称都要求限定符。
假设列
c1
只在表中出现
db1.t
,
c2
只在
db2.t
和
c
两
db1.t
和
db2.t
。
在这种情况下,
c
是不明确的,必须加以限定,但
c1
并
c2
不必是:
SELECT c1,c2,db1.tc FROM db1.t INNER JOIN db2.t WHERE db2.tc> 100;
表别名使得限定列引用更简单:
SELECT c1,c2,t1.c FROM db1.t AS t1 INNER JOIN db2.t AS t2 在哪里t2.c> 100;
在MySQL中,数据库对应于数据目录中的目录。
数据库中的每个表对应于数据库目录中的至少一个文件(并且可能更多,取决于存储引擎)。
触发器也对应于文件。
因此,底层操作系统的区分大小写在数据库,表和触发器名称的区分大小写中起作用。
这意味着这些名称在Windows中不区分大小写,但在大多数Unix中都区分大小写。
一个值得注意的例外是macOS,它是基于Unix的,但使用的是一个不区分大小写的默认文件系统类型(HFS +)。
但是,macOS也支持UFS卷,它在任何Unix上都是区分大小写的。
看到
第1.8.1节“标准SQL的MySQL扩展”
。
所述
lower_case_table_names
系统变量也影响服务器如何处理标识符区分大小写,如在本节后面说明。
虽然数据库,表和触发器名称在某些平台上不区分大小写,但您不应在同一语句中使用不同的情况引用其中一个。
以下语句不起作用,因为它引用了一个表
my_table
,如下所示
MY_TABLE
:
MySQL的> SELECT * FROM my_table WHERE MY_TABLE.col=1;
列,索引,存储例程,事件和资源组名称在任何平台上都不区分大小写,列别名也不区分大小写。
但是,日志文件组的名称区分大小写。 这与标准SQL不同。
默认情况下,表别名在Unix上区分大小写,但在Windows或macOS上不是这样。
以下语句在Unix上不起作用,因为它引用了as
a
和as
的别名
A
:
MySQL的>SELECT
col_name
FROMtbl_name
AS aWHERE a.
col_name
= 1 OR A.col_name
= 2;
但是,Windows上允许使用相同的语句。 为避免此类差异导致的问题,最好采用一致的约定,例如始终使用小写名称创建和引用数据库和表。 建议使用此约定以实现最大的便携性和易用性。
表和数据库名称如何存储在磁盘上并在MySQL中使用受
lower_case_table_names
系统变量的
影响
。
lower_case_table_names
可以采用下表中显示的值。
这个变量不
不
影响触发标识符的情况下的灵敏度。
在Unix上,默认值为
lower_case_table_names
0.在Windows上,默认值为1.在macOS上,默认值为2。
lower_case_table_names
只能在初始化服务器时配置。
lower_case_table_names
禁止在初始化服务器后
更改
设置。
值 | 含义 |
---|---|
0 |
表和数据库名称使用
CREATE
TABLE
or
CREATE
DATABASE
语句中
指定的lettercase存储在磁盘上
。
名称比较区分大小写。
你应该
不会
,如果你有不区分大小写的文件名(如Windows或Mac系统)的系统上运行MySQL这个变量设置为0。
如果使用
--lower-case-table-names=0
不区分大小写的文件系统
强制此变量为0
并
MyISAM
使用不同的字母表
访问
表名,则可能导致索引损坏。
|
1 |
表名以小写形式存储在磁盘上,名称比较不区分大小写。 MySQL在存储和查找时将所有表名转换为小写。 此行为也适用于数据库名称和表别名。 |
2 |
表和数据库名称使用
CREATE
TABLE
or
CREATE
DATABASE
语句中
指定的lettercase存储在磁盘上
,但MySQL在查找时将它们转换为小写。
名称比较不区分大小写。
这
仅适用
于不区分大小写的文件系统!
InnoDB
表名和视图名以小写形式存储,如下所示
lower_case_table_names=1
。
|
如果您只在一个平台上使用MySQL,则通常不必使用
lower_case_table_names
默认设置以外的设置。
但是,如果要在文件系统区分大小写不同的平台之间传输表,则可能会遇到困难。
例如,在Unix上,你可以有两个不同的表名为
my_table
和
MY_TABLE
,但在Windows这两个名字都被认为是相同的。
为避免数据库或表名字母的数据传输问题,您有两种选择:
lower_case_table_names=1
在所有系统上
使用
。
这样做的主要缺点是,当您使用
SHOW
TABLES
或时
SHOW
DATABASES
,您看不到原始字母中的名称。
使用
lower_case_table_names=0
在Unix和
lower_case_table_names=2
Windows上。
这样可以保留数据库和表名的字母大小写。
这样做的缺点是您必须确保您的语句始终在Windows上使用正确的字母大小引用您的数据库和表名。
如果将语句转移到Unix,其中lettercase很重要,如果lettercase不正确,则它们不起作用。
例外
:如果您正在使用
InnoDB
表并且您试图避免这些数据传输问题,则应该
lower_case_table_names=1
在所有平台上使用强制名称转换为小写。
如果对象名称的大写形式根据二进制排序规则相等,则可以认为它们是重复的。
对于游标,条件,过程,函数,保存点,存储的例程参数,存储的程序局部变量和插件的名称都是如此。
对于列,约束,数据库,分区,使用
PREPARE
表,触发器,用户和用户定义变量
准备的语句的名称,情况并非如此
。
文件系统区分大小写可能会影响
INFORMATION_SCHEMA
表的
字符串列中的搜索
。
有关更多信息,请参见
第10.8.7节“在INFORMATION_SCHEMA搜索中使用排序规则”
。
数据库和表标识符与文件系统中的名称之间存在对应关系。 对于基本结构,MySQL将每个数据库表示为数据目录中的目录,并且根据存储引擎,每个表可以由相应数据库目录中的一个或多个文件表示。
对于数据和索引文件,磁盘上的确切表示是特定于存储引擎的。
这些文件可以存储在数据库目录中,或者信息可以存储在单独的文件中。
InnoDB
数据存储在InnoDB数据文件中。
如果您使用表空间
InnoDB
,则
使用
您创建的特定表空间文件。
除ASCII NUL(
X'00'
)
外,任何字符在数据库或表标识符中都是合法的
。
MySQL在创建数据库目录或表文件时对相应文件系统对象中存在问题的任何字符进行编码:
基本拉丁字母(
a..zA..Z
),数字(
0..9
)和下划线(
_
)按原样编码。
因此,它们的区分大小写直接取决于文件系统功能。
来自具有大写/小写映射的字母表的所有其他国家字母编码如下表所示。 “代码范围”列中的值是UCS-2值。
代码范围 | 图案 | 数 | 用过的 | 没用过 | 块 |
---|---|---|---|---|---|
00C0..017F | [@] [0..4] [g..z] | 5 * 20 = 100 | 97 | 3 | Latin-1 Supplement + Latin Extended-A |
0370..03FF | [@] [5..9] [g..z] | 5 * 20 = 100 | 88 | 12 | 希腊语和科普特语 |
0400..052F | [@] [g..z] [0..6] | 20 * 7 = 140 | 137 | 3 | 西里尔文+西里尔文补编 |
0530..058F | [@] [g..z] [7..8] | 20 * 2 = 40 | 38 | 2 | 亚美尼亚 |
2160..217F | [@] [g..z] [9] | 20 * 1 = 20 | 16 | 4 | 数字表格 |
0180..02AF | [@] [g..z] [a..k] | 20 * 11 = 220 | 203 | 17 | Latin Extended-B + IPA扩展 |
1E00..1EFF | [@] [g..z] [l..r] | 20 * 7 = 140 | 136 | 4 | 拉丁语扩展附加 |
1F00..1FFF | [@] [g..z] [s..z] | 20 * 8 = 160 | 144 | 16 | 希腊语扩展 |
.... .... | [@] [A..F] [g..z] | 6 * 20 = 120 | 0 | 120 | RESERVED |
24B6..24E9 | [@] [@] [... Z] | 26 | 26 | 0 | 封闭的字母数字 |
FF21..FF5A | [@] [... Z] [@] | 26 | 26 | 0 | 半宽和全宽形式 |
序列中的一个字节对lettercase进行编码。
例如:
LATIN CAPITAL LETTER A WITH
GRAVE
被编码为
@0G
,而
LATIN SMALL LETTER A WITH GRAVE
被编码为
@0g
。
这里第三个字节(
G
或
g
)表示字母。
(在不区分大小写的文件系统上,两个字母都将被视为相同。)
对于某些块,例如Cyrillic,第二个字节确定字母。 对于其他块,例如Latin1 Supplement,第三个字节确定lettercase。 如果序列中的两个字节是字母(如希腊文扩展中),则最左边的字母代表字母。 所有其他字母字节必须为小写。
除了下划线(
_
)
之外的所有非字母字符
,以及不具有大写/小写映射的字母表中的字母(例如希伯来语)都使用十六进制表示法编码,使用小写字母表示十六进制数字
a..f
:
0x003F - > @ 003f 0xFFFF - > @ffff
十六进制值对应于
ucs2
双字节字符集中的
字符值
。
在Windows上,某些名称(如
nul
,
prn
和)
aux
通过
@@@
在服务器创建相应文件或目录时
附加
到名称
进行编码
。
这种情况发生在所有平台上,以便在平台之间移植相应的数据库对象。
MySQL支持内置(本机)函数,用户定义函数(UDF)和存储函数。 本节介绍服务器如何识别内置函数的名称是用作函数调用还是用作标识符,以及服务器如何确定在具有给定名称的不同类型的函数存在的情况下使用哪个函数。
解析器使用默认规则来解析内置函数的名称。
可以通过启用
IGNORE_SPACE
SQL模式
来更改这些规则
。
当解析器遇到作为内置函数名称的单词时,它必须确定该名称是表示函数调用还是对表达式或列名称等标识符的非表达式引用。
例如,在以下语句中,第一个引用
count
是函数调用,而第二个引用是表名:
SELECT COUNT(*)FROM mytable; CREATE TABLE计数(i INT);
解析器应该识别内置函数的名称,仅在解析预期为表达式的内容时指示函数调用。 也就是说,在非表达式上下文中,允许函数名称作为标识符。
但是,某些内置函数具有特殊的解析或实现注意事项,因此解析器默认使用以下规则来区分它们的名称是用作函数调用还是用作非表达式上下文中的标识符:
要在表达式中将名称用作函数调用,名称和后面的
(
括号字符
之间不能有空格
。
相反,要将函数名称用作标识符,则不能立即使用括号。
在名称和括号之间没有空格的情况下编写函数调用的要求仅适用于具有特殊注意事项的内置函数。
COUNT
就是这样一个名字。
所述
sql/lex.h
源文件列出的这些特殊功能为其以下的空白决定了它们的解释的名称:通过定义的名称
SYM_FN()
中的宏
symbols[]
阵列。
以下列表列出了MySQL 8.0中受
IGNORE_SPACE
设置
影响
并在
sql/lex.h
源文件中
列为特殊的功能
。
您可能会发现将无空白要求视为应用于所有函数调用最简单。
ADDDATE
BIT_AND
BIT_OR
BIT_XOR
CAST
COUNT
CURDATE
CURTIME
DATE_ADD
DATE_SUB
EXTRACT
GROUP_CONCAT
MAX
MID
MIN
NOW
POSITION
SESSION_USER
STD
STDDEV
STDDEV_POP
STDDEV_SAMP
SUBDATE
SUBSTR
SUBSTRING
SUM
SYSDATE
SYSTEM_USER
TRIM
VARIANCE
VAR_POP
VAR_SAMP
对于未列为特殊功能的功能
sql/lex.h
,空白无关紧要。
它们仅在表达式上下文中使用时才被解释为函数调用,否则可以自由地用作标识符。
ASCII
就是这样一个名字。
但是,对于这些不受影响的函数名称,解释可能在表达式上下文中有所不同:
如果存在具有给定名称的函数,则将其解释为内置函数;
如果不存在,
func_name
()
则被解释为用户定义的函数或存储的函数(如果存在该函数)。
func_name
()
在
IGNORE_SPACE
SQL模式可以用来修改分析器把如何运作是空白敏感的名字:
如果
IGNORE_SPACE
禁用,当名称和后面的括号之间没有空格时,解析器会将名称解释为函数调用。
即使在非表达式上下文中使用函数名称,也会发生这种情况:
MySQL的> CREATE TABLE count(i INT);
错误1064(42000):您的SQL语法有错误...
靠近'count(i INT)'
要消除错误并将名称视为标识符,请使用名称后面的空格或将其写为带引号的标识符(或两者):
CREATE TABLE计数(i INT); CREATE TABLE`count`(i INT); CREATE TABLE`count`(i INT);
与
IGNORE_SPACE
启用,解析器放松,有是函数名和其后的括号之间没有空格的要求。
这为编写函数调用提供了更大的灵活性。
例如,以下任一函数调用都是合法的:
SELECT COUNT(*)FROM mytable; SELECT COUNT(*)FROM mytable;
但是,启用
IGNORE_SPACE
还会产生副作用,即解析器将受影响的函数名称视为保留字(请参见
第9.3节“关键字和保留字”
)。
这意味着名称后面的空格不再表示其用作标识符。
该名称可以在具有或不具有跟随空格的函数调用中使用,但在非表达式上下文中会导致语法错误,除非它被引用。
例如,
IGNORE_SPACE
启用时,以下两个语句都会因语法错误而失败,因为解析器将其解释
count
为保留字:
CREATE TABLE计数(i INT); CREATE TABLE计数(i INT);
要在非表达式上下文中使用函数名称,请将其写为带引号的标识符:
CREATE TABLE`count`(i INT); CREATE TABLE`count`(i INT);
要启用
IGNORE_SPACE
SQL模式,请使用以下语句:
SET sql_mode ='IGNORE_SPACE';
IGNORE_SPACE
也可以通过某些其他复合模式启用,例如
ANSI
在其值中包含它:
SET sql_mode ='ANSI';
检查
第5.1.11节“服务器SQL模式”
,以查看启用的复合模式
IGNORE_SPACE
。
要最小化SQL代码对
IGNORE_SPACE
设置
的依赖性
,请使用以下准则:
避免创建与内置函数同名的UDF或存储函数。
避免在非表达式上下文中使用函数名称。
例如,这些语句使用
count
(受影响的受影响的函数名称之一
IGNORE_SPACE
),因此如果
IGNORE_SPACE
启用了
它们,则在名称后面有或没有空格的情况下它们会失败
:
CREATE TABLE计数(i INT); CREATE TABLE计数(i INT);
如果必须在非表达式上下文中使用函数名称,请将其写为带引号的标识符:
CREATE TABLE`count`(i INT); CREATE TABLE`count`(i INT);
以下规则描述了服务器如何解析函数创建和调用的函数名称引用:
内置函数和用户定义函数
如果您尝试创建与内置函数同名的UDF,则会发生错误。
内置功能和存储功能
可以创建与内置函数同名的存储函数,但是要调用存储函数,必须使用模式名称对其进行限定。
例如,如果创建
PI
在
test
模式中
命名的存储函数
,则调用它,
test.PI()
因为服务器在
PI()
没有限定符作为内置函数的引用的情况下
解析
。
如果存储的函数名称与内置函数名称冲突,则服务器会生成警告。
警告可以显示
SHOW
WARNINGS
。
用户定义的函数和存储的函数
用户定义的函数和存储的函数共享相同的名称空间,因此您无法创建具有相同名称的UDF和存储函数。
上述函数名称解析规则对升级到实现新内置函数的MySQL版本有影响:
如果您已经创建了具有给定名称的用户定义函数并将MySQL升级到实现具有相同名称的新内置函数的版本,则UDF将变得不可访问。
要更正此问题,请使用
DROP
FUNCTION
删除UDF并
CREATE
FUNCTION
使用不同的非冲突名称重新创建UDF。
然后修改任何受影响的代码以使用新名称。
如果新版本的MySQL实现了与现有存储函数同名的内置函数,则有两种选择:将存储函数重命名为使用非冲突名称,或者更改对函数的调用,以便它们使用模式限定符(即使用
语法)。
无论哪种情况,请相应地修改任何受影响的代
schema_name
.func_name
()
关键字是在SQL中具有重要意义的单词。
某些关键字,如
SELECT
,
DELETE
或
BIGINT
,被保留,需要用作标识符,例如表和列名特殊待遇。
对于内置函数的名称也可能是这样。
允许非保留关键字作为标识符而不引用。 如果您按 第9.2节“架构对象名称”中 所述引用它们,则允许使用保留字作为标识符 :
MySQL的> CREATE TABLE interval (begin INT, end INT);
错误1064(42000):您的SQL语法有错误...
接近'interval(开始INT,结束INT)'
BEGIN
并且
END
是关键字但不保留,因此它们作为标识符的使用不需要引用。
INTERVAL
是保留关键字,必须引用它作为标识符:
MySQL的> CREATE TABLE `interval` (begin INT, end INT);
查询OK,0行受影响(0.01秒)
例外:限定名称中的句点后面的单词必须是标识符,因此即使保留它也不需要引用:
MySQL的> CREATE TABLE mydb.interval (begin INT, end INT);
查询OK,0行受影响(0.01秒)
允许内置函数的名称作为标识符,但可能需要谨慎使用。
例如,
COUNT
可以接受为列名。
但是,默认情况下,函数名称和后续
(
字符
之间的函数调用中不允许使用空格
。
此要求使解析器能够区分名称是在函数调用中还是在非函数上下文中使用。
有关识别函数名称的更多详细信息,请参见
第9.2.4节“函数名称解析和解析”
。
该
INFORMATION_SCHEMA.KEYWORDS
表列出了MySQL认为是关键字的单词,并指出它们是否被保留。
请参见
第25.14节“INFORMATION_SCHEMA KEYWORDS表”
。
以下列表显示了MySQL 8.0中的关键字和保留字,以及从版本到版本的单个字的更改。
保留关键字标有(R)。
另外,
_FILENAME
是保留。
在某些时候,您可能会升级到更高版本,因此最好还要查看未来的保留字。
您可以在涵盖更高版本MySQL的手册中找到这些内容。
标准SQL中禁止列表中的大多数保留字作为列或表名(例如,
GROUP
)。
一些是保留的,因为MySQL需要它们并使用
yacc
解析器。
A | B | C | D | E | F | G | H | 我 | J | K | L | M | N | O | P | 问 | R | S | T | U | V | W | X | Y | ž
ACCESSIBLE
(R)
ACCOUNT
ACTION
ACTIVE
;
在8.0.14中添加(未保留)
ADD
(R)
ADMIN
;
在8.0.12中未得到保留
AFTER
AGAINST
AGGREGATE
ALGORITHM
ALL
(R)
ALTER
(R)
ALWAYS
ANALYSE
;
在8.0.1中删除
ANALYZE
(R)
AND
(R)
ANY
ARRAY
(R);
在8.0.17中添加(保留)
AS
(R)
ASC
(R)
ASCII
ASENSITIVE
(R)
AT
AUTOEXTEND_SIZE
AUTO_INCREMENT
AVG
AVG_ROW_LENGTH
BACKUP
BEFORE
(R)
BEGIN
BETWEEN
(R)
BIGINT
(R)
BINARY
(R)
BINLOG
BIT
BLOB
(R)
BLOCK
BOOL
BOOLEAN
BOTH
(R)
BTREE
BUCKETS
;
在8.0.2中添加(未保留)
BY
(R)
BYTE
CACHE
CALL
(R)
CASCADE
(R)
CASCADED
CASE
(R)
CATALOG_NAME
CHAIN
CHANGE
(R)
CHANGED
CHANNEL
CHAR
(R)
CHARACTER
(R)
CHARSET
CHECK
(R)
CHECKSUM
CIPHER
CLASS_ORIGIN
CLIENT
CLONE
;
在8.0.3中添加(未保留)
CLOSE
COALESCE
CODE
COLLATE
(R)
COLLATION
COLUMN
(R)
COLUMNS
COLUMN_FORMAT
COLUMN_NAME
COMMENT
COMMIT
COMMITTED
COMPACT
COMPLETION
COMPONENT
COMPRESSED
COMPRESSION
CONCURRENT
CONDITION
(R)
CONNECTION
CONSISTENT
CONSTRAINT
(R)
CONSTRAINT_CATALOG
CONSTRAINT_NAME
CONSTRAINT_SCHEMA
CONTAINS
CONTEXT
CONTINUE
(R)
CONVERT
(R)
CPU
CREATE
(R)
CROSS
(R)
CUBE
(R);
在8.0.1中保留
CUME_DIST
(R);
在8.0.2中添加(保留)
CURRENT
CURRENT_DATE
(R)
CURRENT_TIME
(R)
CURRENT_TIMESTAMP
(R)
CURRENT_USER
(R)
CURSOR
(R)
CURSOR_NAME
DATA
DATABASE
(R)
DATABASES
(R)
DATAFILE
DATE
DATETIME
DAY
DAY_HOUR
(R)
DAY_MICROSECOND
(R)
DAY_MINUTE
(R)
DAY_SECOND
(R)
DEALLOCATE
DEC
(R)
DECIMAL
(R)
DECLARE
(R)
DEFAULT
(R)
DEFAULT_AUTH
DEFINER
DEFINITION
;
在8.0.4中添加(未保留)
DELAYED
(R)
DELAY_KEY_WRITE
DELETE
(R)
DENSE_RANK
(R);
在8.0.2中添加(保留)
DESC
(R)
DESCRIBE
(R)
DESCRIPTION
;
在8.0.4中添加(未保留)
DES_KEY_FILE
;
在8.0.3中删除
DETERMINISTIC
(R)
DIAGNOSTICS
DIRECTORY
DISABLE
DISCARD
DISK
DISTINCT
(R)
DISTINCTROW
(R)
DIV
(R)
DO
DOUBLE
(R)
DROP
(R)
DUAL
(R)
DUMPFILE
DUPLICATE
DYNAMIC
EACH
(R)
ELSE
(R)
ELSEIF
(R)
EMPTY
(R);
在8.0.4中添加(保留)
ENABLE
ENCLOSED
(R)
ENCRYPTION
END
ENDS
ENFORCED
;
在8.0.16中添加(未保留)
ENGINE
ENGINES
ENUM
ERROR
ERRORS
ESCAPE
ESCAPED
(R)
EVENT
EVENTS
EVERY
EXCEPT
(R)
EXCHANGE
EXCLUDE
;
在8.0.2中添加(未保留)
EXECUTE
EXISTS
(R)
EXIT
(R)
EXPANSION
EXPIRE
EXPLAIN
(R)
EXPORT
EXTENDED
EXTENT_SIZE
FALSE
(R)
FAST
FAULTS
FETCH
(R)
FIELDS
FILE
FILE_BLOCK_SIZE
FILTER
FIRST
FIRST_VALUE
(R);
在8.0.2中添加(保留)
FIXED
FLOAT
(R)
FLOAT4
(R)
FLOAT8
(R)
FLUSH
FOLLOWING
;
在8.0.2中添加(未保留)
FOLLOWS
FOR
(R)
FORCE
(R)
FOREIGN
(R)
FORMAT
FOUND
FROM
(R)
FULL
FULLTEXT
(R)
FUNCTION
(R);
在8.0.1中保留
GENERAL
GENERATED
(R)
GEOMCOLLECTION
;
在8.0.11中添加(未保留)
GEOMETRY
GEOMETRYCOLLECTION
GET
(R)
GET_FORMAT
GET_MASTER_PUBLIC_KEY
;
在8.0.4中添加(保留);
在8.0.11中未得到保留
GLOBAL
GRANT
(R)
GRANTS
GROUP
(R)
GROUPING
(R);
在8.0.1中添加(保留)
GROUPS
(R);
在8.0.2中添加(保留)
GROUP_REPLICATION
HANDLER
HASH
HAVING
(R)
HELP
HIGH_PRIORITY
(R)
HISTOGRAM
;
在8.0.2中添加(未保留)
HISTORY
;
在8.0.3中添加(未保留)
HOST
HOSTS
HOUR
HOUR_MICROSECOND
(R)
HOUR_MINUTE
(R)
HOUR_SECOND
(R)
IDENTIFIED
IF
(R)
IGNORE
(R)
IGNORE_SERVER_IDS
IMPORT
IN
(R)
INACTIVE
;
在8.0.14中添加(未保留)
INDEX
(R)
INDEXES
INFILE
(R)
INITIAL_SIZE
INNER
(R)
INOUT
(R)
INSENSITIVE
(R)
INSERT
(R)
INSERT_METHOD
INSTALL
INSTANCE
INT
(R)
INT1
(R)
INT2
(R)
INT3
(R)
INT4
(R)
INT8
(R)
INTEGER
(R)
INTERVAL
(R)
INTO
(R)
INVISIBLE
INVOKER
IO
IO_AFTER_GTIDS
(R)
IO_BEFORE_GTIDS
(R)
IO_THREAD
IPC
IS
(R)
ISOLATION
ISSUER
ITERATE
(R)
JOIN
(R)
JSON
JSON_TABLE
(R);
在8.0.4中添加(保留)
KEY
(R)
KEYS
(R)
KEY_BLOCK_SIZE
KILL
(R)
LAG
(R);
在8.0.2中添加(保留)
LANGUAGE
LAST
LAST_VALUE
(R);
在8.0.2中添加(保留)
LATERAL
(R);
在8.0.14中添加(保留)
LEAD
(R);
在8.0.2中添加(保留)
LEADING
(R)
LEAVE
(R)
LEAVES
LEFT
(R)
LESS
LEVEL
LIKE
(R)
LIMIT
(R)
LINEAR
(R)
LINES
(R)
LINESTRING
LIST
LOAD
(R)
LOCAL
LOCALTIME
(R)
LOCALTIMESTAMP
(R)
LOCK
(R)
LOCKED
;
在8.0.1中添加(未保留)
LOCKS
LOGFILE
LOGS
LONG
(R)
LONGBLOB
(R)
LONGTEXT
(R)
LOOP
(R)
LOW_PRIORITY
(R)
MASTER
MASTER_AUTO_POSITION
MASTER_BIND
(R)
MASTER_CONNECT_RETRY
MASTER_DELAY
MASTER_HEARTBEAT_PERIOD
MASTER_HOST
MASTER_LOG_FILE
MASTER_LOG_POS
MASTER_PASSWORD
MASTER_PORT
MASTER_PUBLIC_KEY_PATH
;
在8.0.4中添加(未保留)
MASTER_RETRY_COUNT
MASTER_SERVER_ID
MASTER_SSL
MASTER_SSL_CA
MASTER_SSL_CAPATH
MASTER_SSL_CERT
MASTER_SSL_CIPHER
MASTER_SSL_CRL
MASTER_SSL_CRLPATH
MASTER_SSL_KEY
MASTER_SSL_VERIFY_SERVER_CERT
(R)
MASTER_TLS_VERSION
MASTER_USER
MATCH
(R)
MAXVALUE
(R)
MAX_CONNECTIONS_PER_HOUR
MAX_QUERIES_PER_HOUR
MAX_ROWS
MAX_SIZE
MAX_UPDATES_PER_HOUR
MAX_USER_CONNECTIONS
MEDIUM
MEDIUMBLOB
(R)
MEDIUMINT
(R)
MEDIUMTEXT
(R)
MEMBER
(R);
在8.0.17中添加(保留)
MEMORY
MERGE
MESSAGE_TEXT
MICROSECOND
MIDDLEINT
(R)
MIGRATE
MINUTE
MINUTE_MICROSECOND
(R)
MINUTE_SECOND
(R)
MIN_ROWS
MOD
(R)
MODE
MODIFIES
(R)
MODIFY
MONTH
MULTILINESTRING
MULTIPOINT
MULTIPOLYGON
MUTEX
MYSQL_ERRNO
NAME
NAMES
NATIONAL
NATURAL
(R)
NCHAR
NDB
NDBCLUSTER
NESTED
;
在8.0.4中添加(未保留)
NETWORK_NAMESPACE
;
在8.0.16中添加(未保留)
NEVER
NEW
NEXT
NO
NODEGROUP
NONE
NOT
(R)
NOWAIT
;
在8.0.1中添加(未保留)
NO_WAIT
NO_WRITE_TO_BINLOG
(R)
NTH_VALUE
(R);
在8.0.2中添加(保留)
NTILE
(R);
在8.0.2中添加(保留)
NULL
(R)
NULLS
;
在8.0.2中添加(未保留)
NUMBER
NUMERIC
(R)
NVARCHAR
OF
(R);
在8.0.1中添加(保留)
OFFSET
OJ
;
在8.0.16中添加(未保留)
OLD
;
在8.0.14中添加(未保留)
ON
(R)
ONE
ONLY
OPEN
OPTIMIZE
(R)
OPTIMIZER_COSTS
(R)
OPTION
(R)
OPTIONAL
;
在8.0.13中添加(未保留)
OPTIONALLY
(R)
OPTIONS
OR
(R)
ORDER
(R)
ORDINALITY
;
在8.0.4中添加(未保留)
ORGANIZATION
;
在8.0.4中添加(未保留)
OTHERS
;
在8.0.2中添加(未保留)
OUT
(R)
OUTER
(R)
OUTFILE
(R)
OVER
(R);
在8.0.2中添加(保留)
OWNER
PACK_KEYS
PAGE
PARSER
PARTIAL
PARTITION
(R)
PARTITIONING
PARTITIONS
PASSWORD
PATH
;
在8.0.4中添加(未保留)
PERCENT_RANK
(R);
在8.0.2中添加(保留)
PERSIST
;
在8.0.16中未得到保留
PERSIST_ONLY
;
在8.0.2中添加(保留);
在8.0.16中未得到保留
PHASE
PLUGIN
PLUGINS
PLUGIN_DIR
POINT
POLYGON
PORT
PRECEDES
PRECEDING
;
在8.0.2中添加(未保留)
PRECISION
(R)
PREPARE
PRESERVE
PREV
PRIMARY
(R)
PRIVILEGES
PROCEDURE
(R)
PROCESS
;
在8.0.11中添加(未保留)
PROCESSLIST
PROFILE
PROFILES
PROXY
PURGE
(R)
QUARTER
QUERY
QUICK
RANGE
(R)
RANK
(R);
在8.0.2中添加(保留)
READ
(R)
READS
(R)
READ_ONLY
READ_WRITE
(R)
REAL
(R)
REBUILD
RECOVER
RECURSIVE
(R);
在8.0.1中添加(保留)
REDOFILE
;
在8.0.3中删除
REDO_BUFFER_SIZE
REDUNDANT
REFERENCE
;
在8.0.4中添加(未保留)
REFERENCES
(R)
REGEXP
(R)
RELAY
RELAYLOG
RELAY_LOG_FILE
RELAY_LOG_POS
RELAY_THREAD
RELEASE
(R)
RELOAD
REMOTE
;
在8.0.3中添加(未保留);
在8.0.14中删除
REMOVE
RENAME
(R)
REORGANIZE
REPAIR
REPEAT
(R)
REPEATABLE
REPLACE
(R)
REPLICATE_DO_DB
REPLICATE_DO_TABLE
REPLICATE_IGNORE_DB
REPLICATE_IGNORE_TABLE
REPLICATE_REWRITE_DB
REPLICATE_WILD_DO_TABLE
REPLICATE_WILD_IGNORE_TABLE
REPLICATION
REQUIRE
(R)
RESET
RESIGNAL
(R)
RESOURCE
;
在8.0.3中添加(未保留)
RESPECT
;
在8.0.2中添加(未保留)
RESTART
;
在8.0.4中添加(未保留)
RESTORE
RESTRICT
(R)
RESUME
RETAIN
;
在8.0.14中添加(未保留)
RETURN
(R)
RETURNED_SQLSTATE
RETURNS
REUSE
;
在8.0.3中添加(未保留)
REVERSE
REVOKE
(R)
RIGHT
(R)
RLIKE
(R)
ROLE
;
在8.0.1中未得到保留
ROLLBACK
ROLLUP
ROTATE
ROUTINE
ROW
(R);
在8.0.2中保留
ROWS
(R);
在8.0.2中保留
ROW_COUNT
ROW_FORMAT
ROW_NUMBER
(R);
在8.0.2中添加(保留)
RTREE
SAVEPOINT
SCHEDULE
SCHEMA
(R)
SCHEMAS
(R)
SCHEMA_NAME
SECOND
SECONDARY
;
在8.0.16中添加(未保留)
SECONDARY_ENGINE
;
在8.0.13中添加(未保留)
SECONDARY_LOAD
;
在8.0.13中添加(未保留)
SECONDARY_UNLOAD
;
在8.0.13中添加(未保留)
SECOND_MICROSECOND
(R)
SECURITY
SELECT
(R)
SENSITIVE
(R)
SEPARATOR
(R)
SERIAL
SERIALIZABLE
SERVER
SESSION
SET
(R)
SHARE
SHOW
(R)
SHUTDOWN
SIGNAL
(R)
SIGNED
SIMPLE
SKIP
;
在8.0.1中添加(未保留)
SLAVE
SLOW
SMALLINT
(R)
SNAPSHOT
SOCKET
SOME
SONAME
SOUNDS
SOURCE
SPATIAL
(R)
SPECIFIC
(R)
SQL
(R)
SQLEXCEPTION
(R)
SQLSTATE
(R)
SQLWARNING
(R)
SQL_AFTER_GTIDS
SQL_AFTER_MTS_GAPS
SQL_BEFORE_GTIDS
SQL_BIG_RESULT
(R)
SQL_BUFFER_RESULT
SQL_CACHE
;
在8.0.3中删除
SQL_CALC_FOUND_ROWS
(R)
SQL_NO_CACHE
SQL_SMALL_RESULT
(R)
SQL_THREAD
SQL_TSI_DAY
SQL_TSI_HOUR
SQL_TSI_MINUTE
SQL_TSI_MONTH
SQL_TSI_QUARTER
SQL_TSI_SECOND
SQL_TSI_WEEK
SQL_TSI_YEAR
SRID
;
在8.0.3中添加(未保留)
SSL
(R)
STACKED
START
STARTING
(R)
STARTS
STATS_AUTO_RECALC
STATS_PERSISTENT
STATS_SAMPLE_PAGES
STATUS
STOP
STORAGE
STORED
(R)
STRAIGHT_JOIN
(R)
STRING
SUBCLASS_ORIGIN
SUBJECT
SUBPARTITION
SUBPARTITIONS
SUPER
SUSPEND
SWAPS
SWITCHES
SYSTEM
(R);
在8.0.3中添加(保留)
TABLE
(R)
TABLES
TABLESPACE
TABLE_CHECKSUM
TABLE_NAME
TEMPORARY
TEMPTABLE
TERMINATED
(R)
TEXT
THAN
THEN
(R)
THREAD_PRIORITY
;
在8.0.3中添加(未保留)
TIES
;
在8.0.2中添加(未保留)
TIME
TIMESTAMP
TIMESTAMPADD
TIMESTAMPDIFF
TINYBLOB
(R)
TINYINT
(R)
TINYTEXT
(R)
TO
(R)
TRAILING
(R)
TRANSACTION
TRIGGER
(R)
TRIGGERS
TRUE
(R)
TRUNCATE
TYPE
TYPES
UNBOUNDED
;
在8.0.2中添加(未保留)
UNCOMMITTED
UNDEFINED
UNDO
(R)
UNDOFILE
UNDO_BUFFER_SIZE
UNICODE
UNINSTALL
UNION
(R)
UNIQUE
(R)
UNKNOWN
UNLOCK
(R)
UNSIGNED
(R)
UNTIL
UPDATE
(R)
UPGRADE
USAGE
(R)
USE
(R)
USER
USER_RESOURCES
USE_FRM
USING
(R)
UTC_DATE
(R)
UTC_TIME
(R)
UTC_TIMESTAMP
(R)
VALIDATION
VALUE
VALUES
(R)
VARBINARY
(R)
VARCHAR
(R)
VARCHARACTER
(R)
VARIABLES
VARYING
(R)
VCPU
;
在8.0.3中添加(未保留)
VIEW
VIRTUAL
(R)
VISIBLE
WAIT
WARNINGS
WEEK
WEIGHT_STRING
WHEN
(R)
WHERE
(R)
WHILE
(R)
WINDOW
(R);
在8.0.2中添加(保留)
WITH
(R)
WITHOUT
WORK
WRAPPER
WRITE
(R)
X509
XA
XID
XML
XOR
(R)
YEAR
YEAR_MONTH
(R)
ZEROFILL
(R)
以下列表显示了与MySQL 5.7相比,MySQL 8.0中添加的关键字和保留字。 保留关键字标有(R)。
A | B | C | D | E | F | G | H | 我 | J | L | M | N | O | P | R | S | T | U | V | w ^
ACTIVE
ADMIN
ARRAY
(R)
BUCKETS
CLONE
COMPONENT
CUME_DIST
(R)
DEFINITION
DENSE_RANK
(R)
DESCRIPTION
EMPTY
(R)
ENFORCED
EXCEPT
(R)
EXCLUDE
FIRST_VALUE
(R)
FOLLOWING
GEOMCOLLECTION
GET_MASTER_PUBLIC_KEY
GROUPING
(R)
GROUPS
(R)
HISTOGRAM
HISTORY
INACTIVE
INVISIBLE
JSON_TABLE
(R)
LAG
(R)
LAST_VALUE
(R)
LATERAL
(R)
LEAD
(R)
LOCKED
MASTER_PUBLIC_KEY_PATH
MEMBER
(R)
NESTED
NETWORK_NAMESPACE
NOWAIT
NTH_VALUE
(R)
NTILE
(R)
NULLS
OF
(R)
OJ
OLD
OPTIONAL
ORDINALITY
ORGANIZATION
OTHERS
OVER
(R)
PATH
PERCENT_RANK
(R)
PERSIST
PERSIST_ONLY
PRECEDING
PROCESS
RANK
(R)
RECURSIVE
(R)
REFERENCE
RESOURCE
RESPECT
RESTART
RETAIN
REUSE
ROLE
ROW_NUMBER
(R)
SECONDARY
SECONDARY_ENGINE
SECONDARY_LOAD
SECONDARY_UNLOAD
SKIP
SRID
SYSTEM
(R)
THREAD_PRIORITY
TIES
UNBOUNDED
VCPU
VISIBLE
WINDOW
(R)
您可以在一个语句中将值存储在用户定义的变量中,稍后在另一个语句中引用它。 这使您可以将值从一个语句传递到另一个语句。
用户变量被写成
,其中变量名
组成的字母数字字符,
,
,和
。
如果引用它作为一个字符串或标识符(例如,用户的变量名可以包含其他字符
,
或
)。
@
var_name
var_name
.
_
$
@'my-var'
@"my-var"
@`my-var`
用户定义的变量是特定于会话的。
其他客户端无法查看或使用由一个客户端定义的用户变量。
(例外:具有访问性能模式的用户
user_variables_by_thread
表的用户可以查看所有会话的所有用户变量。)当客户端退出时,将自动释放给定客户端会话的所有变量。
用户变量名称不区分大小写。 名称的最大长度为64个字符。
设置用户定义变量的一种方法是发出一个
SET
语句:
SET @var_name
=expr
[,@var_name
=expr
] ......
可以从一组有限的数据类型为用户变量分配值:整数,十进制,浮点,二进制或非二进制字符串或
NULL
值。
十进制值和实数值的分配不保留值的精度或比例。
除了允许类型之外的类型的值被转换为允许类型。
例如,具有时间或空间数据类型的值被转换为二进制字符串。
具有
JSON
数据类型的
值将
转换为字符集为的字符串
utf8mb4
和排序规则的
utf8mb4_bin
。
如果为用户变量分配了非二进制(字符)字符串值,则它具有与字符串相同的字符集和排序规则。 用户变量的强制性是隐含的。 (这与表列值的强制性相同。)
分配给用户变量的十六进制或位值被视为二进制字符串。
要将十六进制或位值作为数字分配给用户变量,请在数字上下文中使用它。
例如,添加0或使用
CAST(... AS UNSIGNED)
:
mysql>SET @v1 = X'41';
mysql>SET @v2 = X'41'+0;
mysql>SET @v3 = CAST(X'41' AS UNSIGNED);
mysql>SELECT @v1, @v2, @v3;
+ ------ + ------ + ------ + | @ v1 | @ v2 | @ v3 | + ------ + ------ + ------ + | A | 65 | 65 | + ------ + ------ + ------ + mysql>SET @v1 = b'1000001';
mysql>SET @v2 = b'1000001'+0;
mysql>SET @v3 = CAST(b'1000001' AS UNSIGNED);
mysql>SELECT @v1, @v2, @v3;
+ ------ + ------ + ------ + | @ v1 | @ v2 | @ v3 | + ------ + ------ + ------ + | A | 65 | 65 | + ------ + ------ + ------ +
如果在结果集中选择了用户变量的值,则会将其作为字符串返回给客户端。
如果引用尚未初始化的变量,则其值为
NULL
和字符串类型。
用户变量可以在允许表达式的大多数上下文中使用。
这目前不包括明确要求文字值的上下文,如在
LIMIT
一个条款
SELECT
声明,或
一条款
声明。
IGNORE
N
LINESLOAD DATA
以前的MySQL版本可以在除以外的语句中为用户变量赋值
SET
。
MySQL 8.0支持此功能以实现向后兼容,但在将来的MySQL版本中可能会将其删除。
以这种方式进行赋值时,必须使用
:=
赋值运算符;
=
在除以外的语句中被视为比较运算符
SET
。
涉及用户变量的表达式的评估顺序是未定义的。
例如,无法保证
先
SELECT @a, @a:=@a+1
评估
@a
然后执行分配。
此外,变量的默认结果类型基于其在语句开头的类型。 如果变量在语句的开头保存一种类型的值,并且还为其分配了不同类型的新值,则可能会产生意外的影响。
为了避免这种行为的问题,要么不分配一个值,并在一个语句中读取同一变量的值,否则设置变量
0
,
0.0
或者
''
你使用它之前确定其类型。
HAVING
,
GROUP BY
和
ORDER BY
,当引用在select表达式列表中赋值的变量时,不能按预期工作,因为表达式是在客户端上计算的,因此可以使用前一行中的陈旧列值。
用户变量旨在提供数据值。
它们不能直接在SQL语句中用作标识符或标识符的一部分,例如在需要表或数据库名称的上下文中,或者作为保留字,例如
SELECT
。
即使引用变量也是如此,如以下示例所示:
MySQL的>SELECT c1 FROM t;
+ ---- + | c1 | + ---- + | 0 | + ---- + | 1 | + ---- + 2行(0.00秒) MySQL的>SET @col = "c1";
查询正常,0行受影响(0.00秒) MySQL的>SELECT @col FROM t;
+ ------ + | @col | + ------ + | c1 | + ------ + 1排(0.00秒) mysql> ERROR 1054(42S22):'字段列表'中的未知列'@col'SELECT `@col` FROM t;
mysql> SET @col =“`c1`”; 查询正常,0行受影响(0.00秒) MySQL的>SELECT @col FROM t;
+ ------ + | @col | + ------ + | `c1` | + ------ + 1排(0.00秒)
用户变量不能用于提供标识符的这一原则的一个例外是,当您构造一个字符串以用作稍后执行的预准备语句时。 在这种情况下,用户变量可用于提供语句的任何部分。 以下示例说明了如何完成此操作:
MySQL的>SET @c = "c1";
查询正常,0行受影响(0.00秒) MySQL的>SET @s = CONCAT("SELECT ", @c, " FROM t");
查询正常,0行受影响(0.00秒) MySQL的>PREPARE stmt FROM @s;
查询正常,0行受影响(0.04秒) 声明准备好了 MySQL的>EXECUTE stmt;
+ ---- + | c1 | + ---- + | 0 | + ---- + | 1 | + ---- + 2行(0.00秒) MySQL的>DEALLOCATE PREPARE stmt;
查询正常,0行受影响(0.00秒)
有关 更多信息 , 请参见 第13.5节“准备好的SQL语句语法” 。
可以在应用程序中使用类似的技术来使用程序变量构造SQL语句,如下所示使用PHP 5:
<?PHP $ mysqli = new mysqli(“localhost”,“user”,“pass”,“test”); if(mysqli_connect_errno()) die(“连接失败:%s \ n”,mysqli_connect_error()); $ col =“c1”; $ query =“SELECT $ col FROM t”; $ result = $ mysqli-> query($ query); while($ row = $ result-> fetch_assoc()) { echo“<p>”。$ row [“$ col”]。“</ P> \ n” 个; } $ result->接近(); $ mysqli->接近(); ?>
以这种方式组装SQL语句有时称为 “ 动态SQL ” 。
本节列出了表达式在MySQL中必须遵循的语法规则,并提供了有关表达式中可能出现的术语类型的其他信息。
以下语法规则定义MySQL中的表达式语法。
这里显示的语法基于
sql/sql_yacc.yy
MySQL源代码分发文件中
给出的语法
。
有关某些表达式术语的其他信息,请参阅
表达式术语注释
。
expr
:expr
ORexpr
|expr
||expr
|expr
异或expr
|expr
ANDexpr
|expr
&&expr
| 不是expr
| !expr
|boolean_primary
IS [NOT] {TRUE | FALSE | 未知} |boolean_primary
boolean_primary
:boolean_primary
IS [NOT]为空 |boolean_primary
<=>predicate
| | {ALL | ANY}()boolean_primary
comparison_operator
predicate
boolean_primary
comparison_operator
subquery
|predicate
comparison_operator
:= | > = | > | <= | <| <> | !=predicate
:bit_expr
[NOT] IN(subquery
) |bit_expr
[NOT] IN(expr
[,expr
] ...) |bit_expr
[NOT] BETWEENbit_expr
和predicate
|bit_expr
声音像bit_expr
|bit_expr
[NOT]喜欢simple_expr
[ESCAPEsimple_expr
] |bit_expr
[NOT] REGEXPbit_expr
|bit_expr
bit_expr
:bit_expr
|bit_expr
|bit_expr
&bit_expr
|bit_expr
<<bit_expr
|bit_expr
>>bit_expr
|bit_expr
+bit_expr
|bit_expr
-bit_expr
|bit_expr
*bit_expr
|bit_expr
/bit_expr
|bit_expr
DIVbit_expr
|bit_expr
MODbit_expr
|bit_expr
%bit_expr
|bit_expr
^bit_expr
|bit_expr
+interval_expr
|bit_expr
-interval_expr
|simple_expr
simple_expr
:literal
|identifier
|function_call
|simple_expr
收集collation_name
|param_marker
|variable
|simple_expr
||simple_expr
| +simple_expr
| -simple_expr
| 〜simple_expr
| !simple_expr
| 二进制simple_expr
| (expr
[,expr
] ......) | 行(expr
,expr
[,expr
] ......) | (subquery
) | EXISTS(subquery
) | { }identifier
expr
|match_expr
|case_expr
|interval_expr
有关运算符优先级,请参见 第12.3.1节“运算符优先级” 。 一些运算符的优先级和含义取决于SQL模式:
默认情况下,它
||
是一个逻辑
OR
运算符。
与
PIPES_AS_CONCAT
启用,
||
是字符串连接,与之间的优先级
^
和元运算符。
默认情况下,
!
优先级高于
NOT
。
随着
HIGH_NOT_PRECEDENCE
启用,
!
并且
NOT
具有相同的优先级。
请参见 第5.1.11节“服务器SQL模式” 。
有关文字值语法,请参见 第9.1节“文字值” 。
有关标识符语法,请参见 第9.2节“架构对象名称” 。
变量可以是用户变量,系统变量或存储的程序局部变量或参数:
用户变量: 第9.4节“用户定义的变量”
系统变量: 第5.1.9节“使用系统变量”
存储的程序局部变量: 第13.6.4.1节“局部变量DECLARE语法”
存储的程序参数: 第13.1.17节“创建过程和创建函数语法”
param_marker
是
?
如在用于占位符准备语句使用。
请参见
第13.5.1节“PREPARE语法”
。
(
表示返回单个值的子查询;
也就是说,一个标量子查询。
请参见
第13.2.11.1节“将子查询作为标量操作数”
。
subquery
)
{
是ODBC转义语法,并且可以接受ODBC兼容性。
价值是
identifier
expr
}expr
。
该
{
和
}
在语法花括号应当从字面上写的;
它们不是语法描述中其他地方使用的metasyntax。
match_expr
表示一个
MATCH
表达式。
请参见
第12.9节“全文搜索功能”
。
case_expr
表示一个
CASE
表达式。
请参见
第12.4节“控制流功能”
。
interval_expr
表示时间间隔。
请参阅
时间间隔
。
interval_expr
in表达式表示时间间隔。
间隔具有以下语法:
间隔expr
unit
expr
代表数量。
unit
代表解释数量的单位;
它是一个说明符如
HOUR
,
DAY
,或
WEEK
。
该
INTERVAL
关键字和
unit
符不区分大小写。
下表显示了
expr
每个
unit
值
的
参数
的预期形式
。
表9.2时间间隔表达式和单位参数
unit
值
|
预期
expr
格式
|
---|---|
MICROSECOND |
MICROSECONDS |
SECOND |
SECONDS |
MINUTE |
MINUTES |
HOUR |
HOURS |
DAY |
DAYS |
WEEK |
WEEKS |
MONTH |
MONTHS |
QUARTER |
QUARTERS |
YEAR |
YEARS |
SECOND_MICROSECOND |
'SECONDS.MICROSECONDS' |
MINUTE_MICROSECOND |
'MINUTES:SECONDS.MICROSECONDS' |
MINUTE_SECOND |
'MINUTES:SECONDS' |
HOUR_MICROSECOND |
'HOURS:MINUTES:SECONDS.MICROSECONDS' |
HOUR_SECOND |
'HOURS:MINUTES:SECONDS' |
HOUR_MINUTE |
'HOURS:MINUTES' |
DAY_MICROSECOND |
'DAYS HOURS:MINUTES:SECONDS.MICROSECONDS' |
DAY_SECOND |
'DAYS HOURS:MINUTES:SECONDS' |
DAY_MINUTE |
'DAYS HOURS:MINUTES' |
DAY_HOUR |
'DAYS HOURS' |
YEAR_MONTH |
'YEARS-MONTHS' |
MySQL允许
expr
格式
中的任何标点符号分隔符
。
表中显示的是建议的分隔符。
时间间隔用于某些功能,例如
DATE_ADD()
和
DATE_SUB()
:
MySQL的>SELECT DATE_ADD('2018-05-01',INTERVAL 1 DAY);
- >'2018-05-02' MySQL的>SELECT DATE_SUB('2018-05-01',INTERVAL 1 YEAR);
- >'2017-05-01' mysql>SELECT DATE_ADD('2020-12-31 23:59:59',
- >INTERVAL 1 SECOND);
- > '2021-01-01 00:00:00' mysql>SELECT DATE_ADD('2018-12-31 23:59:59',
- >INTERVAL 1 DAY);
- >'2019-01-01 23:59:59' mysql>SELECT DATE_ADD('2100-12-31 23:59:59',
- >INTERVAL '1:1' MINUTE_SECOND);
- >'2101-01-01 00:01:00' mysql>SELECT DATE_SUB('2025-01-01 00:00:00',
- >INTERVAL '1 1:1:1' DAY_SECOND);
- >'2024-12-30 22:58:59' mysql>SELECT DATE_ADD('1900-01-01 00:00:00',
- >INTERVAL '-1 10' DAY_HOUR);
- >'1899-12-30 14:00:00' MySQL的>SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
- >'1997-12-02' mysql>SELECT DATE_ADD('1992-12-31 23:59:59.000002',
- >INTERVAL '1.999999' SECOND_MICROSECOND);
- >'1993-01-01 00:00:01.000001'
时间算术也可以在
INTERVAL
与
+
or
-
运算符
一起使用的
表达式中执行
:
date
+ INTERVAL - INTERVALexpr
unit
date
expr
unit
INTERVAL
expr
unit
+
如果另一方的表达式是日期或日期时间值,
则允许在
运营商的
任何一方
。
对于
-
操作员,
仅允许在右侧,因为从间隔中减去日期或日期时间值是没有意义的。
INTERVAL
expr
unit
MySQL的>SELECT '2018-12-31 23:59:59' + INTERVAL 1 SECOND;
- >'2019-01-01 00:00:00' MySQL的>SELECT INTERVAL 1 DAY + '2018-12-31';
- >'2019-01-01' MySQL的>SELECT '2025-01-01' - INTERVAL 1 SECOND;
- >'2024-12-31 23:59:59'
该
EXTRACT()
函数使用与
or
相同类型的
unit
说明符
,但从日期中提取部分而不是执行日期算术:
DATE_ADD()
DATE_SUB()
MySQL的>SELECT EXTRACT(YEAR FROM '2019-07-02');
- > 2019年 MySQL的>SELECT EXTRACT(YEAR_MONTH FROM '2019-07-02 01:02:03');
- > 201907
可以在
CREATE
EVENT
语句中
使用时间间隔
:
创造事件myevent 在CURRENT_TIMESTAMP + INTERVAL 1小时的时间表 做 更新myschema.mytable SET mycol = mycol + 1;
如果指定的间隔值太短(不包括
unit
关键字所需的
所有间隔部分
),则MySQL假定您遗漏了间隔值的最左边部分。
例如,如果你指定
unit
的
DAY_SECOND
,价值
expr
预计将有天,小时,分钟和秒部分。
如果指定一个值
'1:10'
,则MySQL假定缺少日期和小时部分,并且值表示分钟和秒。
换句话说,
'1:10' DAY_SECOND
被解释为它等同于
'1:10' MINUTE_SECOND
。
这类似于MySQL解释的方式
TIME
值表示经过的时间而不是一天中的时间。
expr
被视为字符串,因此如果指定了非字符串值,请小心
INTERVAL
。
例如,使用区间说明符
HOUR_MINUTE
,“6/4”被视为6小时,4分钟,而
6/4
评估
1.5000
为1小时5000分钟:
MySQL的>SELECT '6/4', 6/4;
- > 1.5000 MySQL的>SELECT DATE_ADD('2019-01-01', INTERVAL '6/4' HOUR_MINUTE);
- >'2019-01-01 06:04:00' MySQL的>SELECT DATE_ADD('2019-01-01', INTERVAL 6/4 HOUR_MINUTE);
- >'2019-01-04 12:20:00'
为了确保按预期解释间隔值,
CAST()
可以使用操作。
要处理
6/4
为1小时5分钟,请将其转换为
DECIMAL
具有单个小数位
的
值:
MySQL的>SELECT CAST(6/4 AS DECIMAL(3,1));
- > 1.5 mysql>SELECT DATE_ADD('1970-01-01 12:00:00',
- >INTERVAL CAST(6/4 AS DECIMAL(3,1)) HOUR_MINUTE);
- >'1970-01-01 13:05:00'
如果添加或减去包含时间部分的日期值,结果将自动转换为日期时间值:
MySQL的>SELECT DATE_ADD('2023-01-01', INTERVAL 1 DAY);
- >'2023-01-02' MySQL的>SELECT DATE_ADD('2023-01-01', INTERVAL 1 HOUR);
- >'2023-01-01 01:00:00'
如果您添加
MONTH
,,
YEAR_MONTH
或者
YEAR
结果日期的日期大于新月份的最大日期,则将该日期调整为新月份的最大天数:
MySQL的> SELECT DATE_ADD('2019-01-30', INTERVAL 1 MONTH);
- >'2019-02-28'
日期算术运算需要完整日期,不适用于日期不完整
'2016-07-00'
或日期不正确的日期:
MySQL的>SELECT DATE_ADD('2016-07-00', INTERVAL 1 DAY);
- > NULL MySQL的>SELECT '2005-03-32' + INTERVAL 1 MONTH;
- > NULL
MySQL Server支持三种注释样式:
从一个
#
角色到最后一行。
从
--
序列到行尾。
在MySQL中,
--
(双破折号)注释样式要求第二个破折号后跟至少一个空格或控制字符(例如空格,制表符,换行符等)。
此语法与标准SQL注释语法略有不同,如
第1.8.2.4节“' - '作为注释的开头”中所述
。
从
/*
序列到以下
*/
序列,如在C编程语言中。
此语法使注释能够扩展到多行,因为开始和结束序列不必位于同一行。
以下示例演示了所有三种注释样式:
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;
不支持嵌套注释,不推荐使用,并且将在未来的MySQL版本中删除。 (在某些情况下,可能允许嵌套注释,但通常不允许,用户应避免使用它们。)
MySQL Server支持一些C风格注释的变种。 通过使用以下格式的注释,这些使您能够编写包含MySQL扩展的代码,但仍然是可移植的:
/ *!MySQL-specific code
* /
在这种情况下,MySQL Server会像在任何其他SQL语句中那样解析和执行注释中的代码,但其他SQL服务器将忽略这些扩展。
例如,MySQL Server
STRAIGHT_JOIN
在以下语句中
识别
关键字,但其他服务器不会:
选择 /*!STRAIGHT_JOIN * / col1 FROM table1,table2 WHERE ...
如果在
!
字符
后添加版本号
,则仅当MySQL版本大于或等于指定的版本号时,才会执行注释中的语法。
KEY_BLOCK_SIZE
以下注释中
的
关键字仅由MySQL 5.1.10或更高版本的服务器执行:
CREATE TABLE t1(INT,KEY(a))/ *!50110 KEY_BLOCK_SIZE = 1024 * /;
刚才描述的注释语法适用于 mysqld 服务器 如何 解析SQL语句。 在 MySQL的 客户端程序将它们发送到服务器之前还执行语句的一些分析。 (这样做是为了确定多语句输入行中的语句边界。)有关服务器和 mysql clinet 解析器 之间差异的信息 ,请参见 第4.5.1.6节“mysql客户端提示” 。
/*!12345 ... */
格式的
注释
不存储在服务器上。
如果使用此格式对存储的程序进行注释,则注释不会保留在程序正文中。
C风格注释语法的另一种变体用于指定优化器提示。
提示注释包括
注释开始序列
+
后面的字符
/*
。
例:
SELECT / * + BKA(t1)* / FROM ...;
有关更多信息,请参见 第8.9.3节“优化程序提示” 。
不支持
使用短格式
mysql
命令,例如
\C
在多行
/* ...
*/
注释中。