字面值

    TiDB 字面值包括字符字面值、数值字面值、时间日期字面值、十六进制、二进制字面值和 NULL 字面值。以下分别对这些字面值进行一一介绍。

    String Literals 是一个 bytes 或者 characters 的序列,两端被单引号 或者双引号 " 包围,例如:

    如果字符串是连续的,会被合并为一个独立的 string。以下表示是一样的:

    1. 'a string'
    2. 'a' ' ' 'string'
    3. "a" ' ' "string"

    如果开启了 ANSI_QUOTES SQL MODE,那么只有单引号内的会被认为是 String Literals,对于双引号内的字符串,会被认为是一个 identifier。

    字符串分为以下两种:

    • 二进制字符串 (binary string):由字节序列构成,它的 charset 和 collation 都是 binary,在互相比较时利用字节作为单位。
    • 非二进制字符串:由字符序列构成,有除 binary 以外的多种 charset 和 collation,在相互比较时用字符(一个字符可能包含多个字节,取决于 charset 的选择)作为单位。

    一个 String Literal 可以拥有一个可选的 character set introducerCOLLATE clause,可以用来指定特定的 charset 和 collation。

    1. [_charset_name]'string' [COLLATE collation_name]

    例如:

    1. SELECT _latin1'string';
    2. SELECT _binary'string';
    3. SELECT _utf8'string' COLLATE utf8_bin;

    你可以使用 N'literal' 或者 n'literal' 来创建使用 national character set 的字符串,下列语句是一样的:

    1. SELECT N'some text';
    2. SELECT n'some text';
    3. SELECT _utf8'some text';

    要在字符串中表示某些特殊字符,可以利用转义字符进行转义:

    如果要在 ' 包围的字符串中表示 ",或者在 " 包围的字符串中表示 ',可以不使用转义字符。

    更多细节见 。

    Numeric Literals

    数值字面值包括 integer 跟 Decimal 类型跟浮点数字面值。

    integer 可以包括 . 作为小数点分隔,数字前可以有 - 或者 + 来表示正数或者负数。

    科学记数法也是被允许的,表示为如下格式:1.2E3, 1.2E-3, -1.2E3, -1.2E-3

    更多细节见 MySQL 官方文档

    Date 跟 Time 字面值有几种格式,例如用字符串表示,或者直接用数字表示。在 TiDB 里面,当 TiDB 期望一个 Date 的时候,它会把 '2017-08-24''20170824'20170824 当做是 Date。

    TiDB 的 Date 值有以下几种格式:

    • 'YYYY-MM-DD' 或者 'YY-MM-DD',这里的 - 分隔符并不是严格的,可以是任意的标点符号。比如 '2017-08-24''2017&08&24''2012@12^31' 都是一样的。唯一需要特别对待的是 ‘.’ 号,它被当做是小数点,用于分隔整数和小数部分。

      Date 和 Time 部分可以被 ‘T’ 分隔,它的作用跟空格符是一样的,例如 2017-8-24 10:42:002017-8-24T10:42:00 是一样的。

    • 'YYYYMMDDHHMMSS' 或者 'YYMMDDHHMMSS',例如 '20170824104520''170824104520' 被当做是 '2017-08-24 10:45:20',但是如果你提供了一个超过范围的值,例如,那这就不是一个有效的 Date 字面值。

    • YYYYMMDDHHMMSS 或者 YYMMDDHHMMSS,注意这里没有单引号或者双引号,是一个数字。例如 20170824104520表示为 '2017-08-24 10:45:20'

    DATETIME 或者 TIMESTAMP 值可以接一个小数部分,用来表示微秒(精度最多到小数点后 6 位),用小数点 . 分隔。

    如果 Date 的 year 部分只有两个数字,这是有歧义的(推荐使用四个数字的格式),TiDB 会尝试用以下的规则来解释:

    • year 值如果在 70-99 范围,那么被转换成 1970-1999
    • year 值如果在 00-69 范围,那么被转换成 2000-2069

    对于小于 10 的 month 或者 day 值,'2017-8-4''2017-08-04' 是一样的。对于 Time 也是一样,比如 '2017-08-24 1:2:3''2017-08-24 01:02:03'是一样的。

    在需要 Date 或者 Time 的语境下, 对于数值,TiDB 会根据数值的长度来选定指定的格式:

    • 12 个数字,会被解释为 YYMMDDHHMMSS
    • 8 个数字,会解释为 YYYYMMDD
    • 14 个数字,会被解释为 YYYYMMDDHHMMSS

    对于 Time 类型,TiDB 用以下格式来表示:

    • 'D HH:MM:SS',或者 'HH:MM:SS''HH:MM''D HH:MM''D HH''SS',这里的 D 表示 days,合法的范围是 0-34
    • 数值 HHMMSS,例如 231010 被解释为'23:10:10'
    • 数值 SSMMSSHHMMSS 都是可以被当做 Time。

    Time 类型的小数点也是 .,精度最多小数点后 6 位。

    Boolean Literals

    常量 TRUEFALSE 等于 1 和 0,它是大小写不敏感的。

    1. SELECT TRUE, true, tRuE, FALSE, FaLsE, false;

    十六进制字面值是有 X0x 前缀的字符串,后接表示十六进制的数字。注意 0x 是大小写敏感的,不能表示为 0X

    例:

    1. X'ac12'
    2. X'12AC'
    3. x'ac12'
    4. x'12AC'
    5. 0xac12

    以下是不合法的十六进制字面值:

    1. X'1z' (z 不是合法的十六进制值)
    2. 0X12AC (0X 必须用小写的 0x)

    对于使用 X'val' 格式的十六进制字面值,val 必须要有一个数字,可以在前面补一个 0 来避免语法错误。

    1. select X'aff';
    1. ERROR 1105 (HY000): line 0 column 13 near ""hex literal: invalid hexadecimal format, must even numbers, but 3 (total length 13)
    1. select X'0aff';

    默认情况,十六进制字面值是一个二进制字符串。

    如果需要将一个字符串或者数字转换为十六进制字面值,可以使用内建函数 HEX()

    1. SELECT HEX('TiDB');
    1. +-------------+
    2. | HEX('TiDB') |
    3. +-------------+
    4. | 54694442 |
    5. +-------------+
    1. SELECT X'54694442';
    1. +-------------+
    2. | X'54694442' |
    3. +-------------+
    4. | TiDB |
    5. +-------------+
    6. 1 row in set (0.00 sec)

    Bit-Value Literals

    位值字面值用 b 或者 0b 做前缀,后接以 0 和 1 组成的二进制数字。其中 0b 是区分大小写的,0B 则会报错。

    合法的 Bit-value:

    • b’01’
    • B’01’
    • 0b01

    非法的 Bit-value:

    • b’2’ (2 不是二进制数值, 必须为 0 或 1)
    • 0B01 (0B 必须是小写 0b)

    默认情况,位值字面值是一个二进制字符串。

    Bit-value 是作为二进制返回的,所以输出到 MySQL Client 可能会无法显示,如果要转换为可打印的字符,可以使用内建函数 BIN() 或者 HEX()

    1. CREATE TABLE t (b BIT(8));
    2. INSERT INTO t SET b = b'00010011';
    3. INSERT INTO t SET b = b'1110';
    4. INSERT INTO t SET b = b'100101';
    1. +------+--------+--------+
    2. | b+0 | BIN(b) | HEX(b) |
    3. +------+--------+--------+
    4. | 19 | 10011 | 13 |
    5. | 14 | 1110 | E |
    6. | 37 | 100101 | 25 |
    7. +------+--------+--------+
    8. 3 rows in set (0.00 sec)

    NULL 代表数据为空,它是大小写不敏感的,与 \N(大小写敏感)同义。