第9章语言结构

目录

9.1字面值
9.1.1字符串文字
9.1.2数字文字
9。1日期和时间文字
9.1.4十六进制文字
9.1.5比特值文字
9.1.6布尔文字
9.1.7 NULL值
9.2模式对象名称
9.2.1标识符限定符
9.2.2标识符区分大小写
9.2.3标识符到文件名的映射
9.2.4函数名称解析和解析
9.3关键字和保留字
9.4用户定义的变量
9.5表达式
9.6注释语法

本章讨论 使用MySQL时 编写以下 SQL 语句 元素的规则

9.1字面值

本节介绍如何在MySQL中编写文字值。 这些包括字符串,数字,十六进制和位值,布尔值和 NULL 本节还介绍了在MySQL中处理这些基本类型时可能遇到的各种细微差别。

9.1.1字符串文字

字符串是一个字节或字符序列,包含在单引号( ' )或双引号( " )字符中。 例子:

'一个字符串'
“另一个字符串”

彼此相邻的带引号的字符串连接成一个字符串。 以下行是等效的:

'一个字符串'
'a'''''字符串'

如果 ANSI_QUOTES 启用 SQL模式,则只能在单引号内引用字符串文字,因为在双引号内引用的字符串将被解释为标识符。

二进制串 是一个字节的字符串。 每个二进制字符串都有一个字符集和排序规则 binary 一个 非二进制字符串 是字符的字符串。 它具有除字符集以外的字符集 binary 和与字符集兼容的排序规则。

对于这两种类型的字符串,比较基于字符串单元的数值。 对于二进制字符串,单位是字节; 比较使用数字字节值。 对于非二进制字符串,单位是字符,一些字符集支持多字节字符; 比较使用数字字符代码值。 字符代码排序是字符串排序规则的一个功能。 (有关更多信息,请参见 第10.8.5节“二进制排序与_bin排序相比” 。)

字符串文字可以具有可选的字符集介绍人和 COLLATE 子句,以将其指定为使用特定字符集和排序规则的字符串:

[_ charset_name]' string'[收集collation_name]

例子:

SELECT _latin1' string';
SELECT _binary' string';
SELECT _utf8''COLLATE stringutf8_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 启用S​​QL模式, 否则某些序列具有特殊含义 这些序列中的每一个都以反斜杠( \ 开头 ,称为 转义字符 MySQL识别 表9.1“特殊字符转义序列”中显示的转义序列 对于所有其他转义序列,将忽略反斜杠。 也就是说,转义字符被解释为好像它没有被转义。 例如, \x 就是这样 x 这些序列区分大小写。 例如, \b 被解释为退格,但 \B 被解释为 B 根据 character_set_connection 系统变量 指示的字符集完成转义处理 即使对于前导有指示不同字符集的介绍人的字符串也是如此,如 第10.3.6节“字符串文字字符集和排序规则”中所述

表9.1特殊字符转义序列

逃脱序列 由Sequence表示的字符
\0 ASCII NUL( X'00' )字符
\' 单引号( ' )字符
\" 双引号( " )字符
\b 退格字符
\n 换行符(换行符)
\r 回车符
\t 制表符
\Z ASCII 26(Control + Z); 见表格后面的注释
\\ 反斜杠( \ )字符
\% 一个 % 角色; 见表格后面的注释
\_ 一个 _ 角色; 见表格后面的注释

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负责为您转义值中的特殊字符。

9.1.2数字文字

数字文字包括精确值(整数和 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

整数可以用在浮点上下文中; 它被解释为等效的浮点数。

9。1日期和时间文字

日期和时间值可以用多种格式表示,例如带引号的字符串或数字,具体取决于值的确切类型和其他因素。 例如,在上下文中,其中的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'

9.1.4十六进制文字

十六进制文字值使用 表示法 编写 ,其中 包含十六进制数字( )。 数字和任何领先的字母 都没关系。 前导 区分大小写,不能写为 X'val' 0xval 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秒)

使用 包含奇数位数的符号 写入的值 被视为具有额外的前导 例如, 被解释为 0xval 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'[COLLATE collation_name]

例子:

SELECT _latin1 X'4D7953514C';
SELECT _utf8 0x4D7953514C COLLATE utf8_danish_ci;

这些示例使用 符号,但 符号也允许引入者。 有关介绍人的信息,请参见 第10.3.8节“字符集介绍人” X'val' 0xval

在数字上下文中,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位数。

9.1.5比特值文字

位值文字是使用 表示法 编写的 是使用零和1写的二进制值。 任何领导的信件 都没关系。 前导 区分大小写,不能写为 b'val' 0bval 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'[COLLATE collation_name]

例子:

SELECT _latin1 b'1000001';
SELECT _utf8 0b1000001 COLLATE utf8_danish_ci;

这些示例使用 符号,但 符号也允许引入者。 有关介绍人的信息,请参见 第10.3.8节“字符集介绍人” b'val' 0bval

在数字上下文中,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位数。

9.1.6布尔文字

常数 TRUE 分别 FALSE 评估 1 0 常量名称可以写在任何字母表中。

MySQL的> SELECT TRUE, true, FALSE, false;
        - > 1,1,0,0

9.1.7 NULL值

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 值在升序排序的其他值之前排序,在降序排序的其他值之后排序。

9.2模式对象名称

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 |
+ ----- + ----- +

在语句的其他地方,对别名的引用引用必须使用标识符引用,或者引用被视为字符串文字。

建议您不要使用以 Me ,where 整数 开头的名称 例如,避免使用 作为标识符,因为表达式 是不明确的。 根据上下文,它可能被解释为表达式 或数字 MeN 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集群中的数据库对象关联的限制”

9.2.1标识符限定符

对象名称可能不合格或合格。 在名称解释明确无误的情况下,允许使用非限定名称。 限定名称包括至少一个限定符,以通过覆盖默认上下文或提供缺少的上下文来阐明解释上下文。

例如,此语句使用非限定名称创建表 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;

9.2.2标识符区分大小写

在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 FROM tbl_name AS a
       WHERE 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搜索中使用排序规则”

9.2.3标识符到文件名的映射

数据库和表标识符与文件系统中的名称之间存在对应关系。 对于基本结构,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 通过 @@@ 在服务器创建相应文件或目录时 附加 到名称 进行编码 这种情况发生在所有平台上,以便在平台之间移植相应的数据库对象。

9.2.4函数名称解析和解析

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()

9.3关键字和保留字

关键字是在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关键字和保留字

以下列表显示了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

C

  • 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

d

  • 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

F

  • 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中保留

G

  • 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

H

  • 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

P

  • 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)

Q

  • QUARTER

  • QUERY

  • QUICK

[R

  • 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)

V

  • VALIDATION

  • VALUE

  • VALUES (R)

  • VARBINARY (R)

  • VARCHAR (R)

  • VARCHARACTER (R)

  • VARIABLES

  • VARYING (R)

  • VCPU ; 在8.0.3中添加(未保留)

  • VIEW

  • VIRTUAL (R)

  • VISIBLE

w ^

  • WAIT

  • WARNINGS

  • WEEK

  • WEIGHT_STRING

  • WHEN (R)

  • WHERE (R)

  • WHILE (R)

  • WINDOW (R); 在8.0.2中添加(保留)

  • WITH (R)

  • WITHOUT

  • WORK

  • WRAPPER

  • WRITE (R)

X

  • X509

  • XA

  • XID

  • XML

  • XOR (R)

ÿ

  • YEAR

  • YEAR_MONTH (R)

ž

  • ZEROFILL (R)

MySQL 8.0新关键字和保留字

以下列表显示了与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

C

  • CLONE

  • COMPONENT

  • CUME_DIST (R)

d

  • DEFINITION

  • DENSE_RANK (R)

  • DESCRIPTION

Ë

  • EMPTY (R)

  • ENFORCED

  • EXCEPT (R)

  • EXCLUDE

F

  • FIRST_VALUE (R)

  • FOLLOWING

G

  • GEOMCOLLECTION

  • GET_MASTER_PUBLIC_KEY

  • GROUPING (R)

  • GROUPS (R)

H

  • 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)

P

  • PATH

  • PERCENT_RANK (R)

  • PERSIST

  • PERSIST_ONLY

  • PRECEDING

  • PROCESS

[R

  • 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

V

  • VCPU

  • VISIBLE

w ^

  • WINDOW (R)

MySQL 8.0删除了关键字和保留字

以下列表显示了与MySQL 5.7相比,在MySQL 8.0中删除的关键字和保留字。 保留关键字标有(R)。

  • ANALYSE

  • DES_KEY_FILE

  • PARSE_GCOL_EXPR

  • REDOFILE

  • SQL_CACHE

9.4用户定义的变量

您可以在一个语句中将值存储在用户定义的变量中,稍后在另一个语句中引用它。 这使您可以将值从一个语句传递到另一个语句。

用户变量被写成 ,其中变量名 组成的字母数字字符, ,和 如果引用它作为一个字符串或标识符(例如,用户的变量名可以包含其他字符 )。 @var_name var_name . _ $ @'my-var' @"my-var" @`my-var`

用户定义的变量是特定于会话的。 其他客户端无法查看或使用由一个客户端定义的用户变量。 (例外:具有访问性能模式的用户 user_variables_by_thread 表的用户可以查看所有会话的所有用户变量。)当客户端退出时,将自动释放给定客户端会话的所有变量。

用户变量名称不区分大小写。 名称的最大长度为64个字符。

设置用户定义变量的一种方法是发出一个 SET 语句:

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

对于 SET = 或者 := 可以用作赋值运算符。

可以从一组有限的数据类型为用户变量分配值:整数,十进制,浮点,二进制或非二进制字符串或 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 LINES LOAD 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

9.5表达式

本节列出了表达式在MySQL中必须遵循的语法规则,并提供了有关表达式中可能出现的术语类型的其他信息。

表达式语法

以下语法规则定义MySQL中的表达式语法。 这里显示的语法基于 sql/sql_yacc.yy MySQL源代码分发文件中 给出的语法 有关某些表达式术语的其他信息,请参阅 表达式术语注释

exprexprOR expr
  | expr|| expr
  | expr异或expr
  | exprAND expr
  | expr&& expr
  | 不是expr
  | expr
  | boolean_primaryIS [NOT] {TRUE | FALSE | 未知}
  | boolean_primary

boolean_primaryboolean_primary IS [NOT]为空
  | boolean_primary<=> predicate
  | 
  | {ALL | ANY}(boolean_primary comparison_operator predicateboolean_primary comparison_operatorsubquery
  | predicate

comparison_operator:= | > = | > | <= | <| <> | !=

predicatebit_expr[NOT] IN(subquery
  | bit_expr[NOT] IN(expr[,expr] ...)
  | bit_expr[NOT] BETWEEN bit_exprpredicate
  | bit_expr声音像bit_expr
  | bit_expr[NOT]喜欢simple_expr[ESCAPE simple_expr]
  | bit_expr[NOT] REGEXP bit_expr
  |bit_expr

bit_exprbit_expr| bit_expr
  | bit_exprbit_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_exprDIV bit_expr
  | bit_exprMOD bit_expr
  | bit_exprbit_expr
  | bit_expr^ bit_expr
  | bit_expr+ interval_expr
  | bit_expr- interval_expr
  |simple_expr

simple_exprliteral
  | 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] ......)
  | 行(exprexpr[,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节“架构对象名称”

变量可以是用户变量,系统变量或存储的程序局部变量或参数:

param_marker ? 如在用于占位符准备语句使用。 请参见 第13.5.1节“PREPARE语法”

(subquery) 表示返回单个值的子查询; 也就是说,一个标量子查询。 请参见 第13.2.11.1节“将子查询作为标量操作数”

{identifier expr} 是ODBC转义语法,并且可以接受ODBC兼容性。 价值是 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
dateexpr 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

9.6注释语法

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 在多行 /* ... */ 注释中。

原文