字符串函数

TiDB 支持使用大部分 MySQL 5.7 中提供的字符串函数、一部分 MySQL 8.0 中提供的字符串函数和一部分 Oracle 21 所提供的函数

关于 Oracle 函数和 TiDB 函数的对照关系,请参考 Oracle 与 TiDB 函数和语法差异对照

支持的函数

ASCII()

ASCII() 函数用于获取输入的参数中最左字符的 ASCII 值。该参数可以为字符串或数字。

  • 如果输入参数不为空,该函数返回参数中最左字符的 ASCII 值。
  • 如果输入参数为空字符串,该函数返回 0
  • 如果输入参数为 NULL,该函数返回 NULL

查询示例:

SELECT ASCII('A'), ASCII('TiDB'), ASCII(23);

返回结果:

+------------+---------------+-----------+ | ASCII('A') | ASCII('TiDB') | ASCII(23) | +------------+---------------+-----------+ | 65 | 84 | 50 | +------------+---------------+-----------+

BIN()

BIN() 函数用于将输入的参数转换为其二进制值的字符串表示形式。该参数可以为字符串或数字。

  • 如果输入参数为正数,该函数返回该参数的二进制值的字符串表示形式。
  • 如果输入参数为负数,该函数会将该参数的绝对值转换为其二进制值,然后对二进制值的每位取反(0 变为 11 变为 0),最后加上 1
  • 如果输入参数为字符串,且该字符串中只包含数字,该函数将按照该数字返回结果。例如,"123"123 的返回结果相同。
  • 如果输入参数为字符串,且该字符串第一个字符不是数字(如 "q123"),该函数返回 0
  • 如果输入参数为字符串,且该字符串由数字和非数字组成,该函数将按照该参数中最前面连续的数字返回结果。例如,'123q123'123 的返回结果相同,但 BIN('123q123') 会产生一个 Truncated incorrect INTEGER value: '123q123' 的警告。
  • 如果输入参数为 NULL,该函数返回 NULL

查询示例 1:

SELECT BIN(123), BIN('123q123');

返回结果 1:

+----------+----------------+ | BIN(123) | BIN('123q123') | +----------+----------------+ | 1111011 | 1111011 | +----------+----------------+

查询示例 2:

SELECT BIN(-7);

返回结果 2:

+------------------------------------------------------------------+ | BIN(-7) | +------------------------------------------------------------------+ | 1111111111111111111111111111111111111111111111111111111111111001 | +------------------------------------------------------------------+

BIT_LENGTH()

返回字符串的位长度

CHAR()

返回由整数的代码值所给出的字符组成的字符串

CHAR_LENGTH()

返回字符串的字符长度

CHARACTER_LENGTH()

CHAR_LENGTH() 功能相同

CONCAT()

返回连接的字符串

CONCAT_WS()

返回由分隔符连接的字符串

ELT()

返回指定位置的字符串

EXPORT_SET()

返回一个字符串,其中值位中设置的每个位,可以得到一个 on 字符串,而每个未设置的位,可以得到一个 off 字符串

FIELD()

返回参数在后续参数中出现的第一个位置

FIND_IN_SET()

返回第一个参数在第二个参数中出现的位置

FORMAT()

FORMAT(X,D[,locale]) 函数用于将数字 X 格式化为类似于 “#,###,###.##” 的格式,四舍五入保留 D 位小数,并将结果作为字符串返回。

参数:

  • X:要格式化的数字。可以是直接的数字值、数字字符串、或科学记数法格式的数字。
  • D:指定返回值的小数位数。该函数根据 DX 进行四舍五入。如果 D 大于 X 的实际小数位数,则会在结果中填充相应长度的零。
  • [locale]:指定一个区域设置,用于结果中数字的小数点、千位分隔符和分隔符之间的分组。合法的区域设置值与 lc_time_names 系统变量的合法值相同。如果未指定或者设置为 NULL,则默认使用 'en_US' 区域设置。该参数可选。

行为细节:

  • 如果输入的第一个参数为字符串,且该字符串中只包含数字时,该函数将按照该数字返回结果。例如,FORMAT('12.36', 1)FORMAT(12.36, 1) 的返回结果相同。
  • 如果输入的第一个参数为科学计数法(E/e)表示的数字时,该函数将按照该数字返回结果。例如,FORMAT('1E2', 3)),函数返回 100.000
  • 如果输入的第一个参数为非数字开头的字符串时,该函数除了返回零值外,还返回一个警告 (Code 1292)。例如,FORMAT('q12.36', 5) 函数返回 0.00000,还会包含一个警告 Warning (Code 1292): Truncated incorrect DOUBLE value: 'q12.36'
  • 如果输入的第一个参数为数字和非数字混合的字符串时,该函数将基于该参数中开头连续的数字部分返回结果,还返回一个警告 (Code 1292)。例如,FORMAT('12.36q56.78', 1)FORMAT('12.36', 1) 的返回的数字结果相同,但 FORMAT('12.36q56.78', 1) 还会包含一个警告 Warning (Code 1292): Truncated incorrect DOUBLE value: '12.36q56.78'
  • 如果输入的第二个参数为零或负数,该函数将四舍五入小数部分并返回整数。
  • 如果输入的任意参数为 NULL,函数将返回 NULL

示例:

格式化数字 12.36 到不同的小数位数:

mysql> SELECT FORMAT(12.36, 1); +------------------+ | FORMAT(12.36, 1) | +------------------+ | 12.4 | +------------------+
mysql> SELECT FORMAT(12.36, 5); +------------------+ | FORMAT(12.36, 5) | +------------------+ | 12.36000 | +------------------+
mysql> SELECT FORMAT(1234.56, 1, 'en_US'); +-----------------------------+ | FORMAT(1234.56, 1, 'en_US') | +-----------------------------+ | 1,234.6 | +-----------------------------+

FROM_BASE64()

FROM_BASE64(str) 函数用于对 Base64 编码的字符串进行解码,并将解码结果以十六进制字符串的形式返回。

  • 此函数接受一个单一参数,即需要解码的 Base64 编码字符串。
  • 如果输入参数为 NULL 或无效的 Base64 编码字符串,FROM_BASE64() 函数将返回 NULL

示例:

以下示例解码 Base64 编码的字符串 'SGVsbG8gVGlEQg==',该字符串是 'Hello TiDB' 经过 TO_BASE64() 函数编码的结果。

mysql> SELECT TO_BASE64('Hello TiDB'); +-------------------------+ | TO_BASE64('Hello TiDB') | +-------------------------+ | SGVsbG8gVGlEQg== | +-------------------------+ mysql> SELECT FROM_BASE64('SGVsbG8gVGlEQg=='); +------------------------------------------------------------------+ | FROM_BASE64('SGVsbG8gVGlEQg==') | +------------------------------------------------------------------+ | 0x48656C6C6F2054694442 | +------------------------------------------------------------------+
mysql> SELECT CONVERT(FROM_BASE64('SGVsbG8gVGlEQg==') USING utf8mb4); +--------------------------------------------------------+ | CONVERT(FROM_BASE64('SGVsbG8gVGlEQg==') USING utf8mb4) | +--------------------------------------------------------+ | Hello TiDB | +--------------------------------------------------------+

以下示例解码 Base64 编码的数字 MTIzNDU2,该字符串是 123456 经过 TO_BASE64() 函数编码的结果。

mysql> SELECT FROM_BASE64('MTIzNDU2'); +--------------------------------------------------+ | FROM_BASE64('MTIzNDU2') | +--------------------------------------------------+ | 0x313233343536 | +--------------------------------------------------+

HEX()

返回一个十进制数或字符串值的 16 进制表示

INSERT()

在指定位置插入一个子字符串,最多不超过指定字符数

INSTR()

返回第一次出现的子字符串的索引

LCASE()

LOWER() 功能相同

LEFT()

返回最左侧指定长度的字符

LENGTH()

返回字符串长度,单位为字节

LIKE

进行简单模式匹配

LOCATE()

返回第一次出现的子字符串的位置

LOWER()

返回全小写的参数

LPAD()

返回字符串参数,左侧添加指定字符串

LTRIM()

去掉前缀空格

MAKE_SET()

返回一组用逗号分隔的字符串,这些字符串的位数与给定的 bits 参数对应

MID()

返回一个以指定位置开始的子字符串

NOT LIKE

否定简单模式匹配

NOT REGEXP

REGEXP 的否定形式

OCT()

返回一个数值的八进制表示,形式为字符串

OCTET_LENGTH()

LENGTH() 功能相同

ORD()

返回该参数最左侧字符的字符编码

POSITION()

LOCATE() 功能相同

QUOTE()

使参数逃逸,为了在 SQL 语句中使用

REGEXP

使用正则表达式匹配模式

REGEXP_INSTR()

返回满足正则的子字符串的第一个索引位置(与 MySQL 不完全兼容,具体请参考正则函数与 MySQL 的兼容性

REGEXP_LIKE()

判断字符串是否满足正则表达式(与 MySQL 不完全兼容,具体请参考正则函数与 MySQL 的兼容性

REGEXP_REPLACE()

替换满足正则表达式的子字符串(与 MySQL 不完全兼容,具体请参考正则函数与 MySQL 的兼容性

REGEXP_SUBSTR()

返回满足正则表达式的子字符串(与 MySQL 不完全兼容,具体请参考正则函数与 MySQL 的兼容性

REPEAT()

以指定次数重复一个字符串

REPLACE()

替换所有出现的指定字符串

REVERSE()

反转字符串里的所有字符

返回指定数量的最右侧的字符

RLIKE

REGEXP 功能相同

RPAD()

以指定次数添加字符串

RTRIM()

去掉后缀空格

SPACE()

返回指定数量的空格,形式为字符串

STRCMP()

比较两个字符串

SUBSTR()

返回指定的子字符串

SUBSTRING()

返回指定的子字符串

SUBSTRING_INDEX()

从一个字符串中返回指定出现次数的定界符之前的子字符串

TO_BASE64()

返回转化为 base-64 表示的字符串参数

TRANSLATE()

将字符串中出现的所有指定字符替换为其它字符。这个函数不会像 Oracle 一样将空字符串视为NULL

TRIM()

去掉前缀和后缀空格

UCASE()

UCASE() 函数将字符串转换为大写字母,此函数等价于 UPPER() 函数。

查询示例:

SELECT UPPER('bigdata') AS result_upper, UPPER(null) AS result_null;

返回结果:

+--------------+-------------+ | result_upper | result_null | +--------------+-------------+ | BIGDATA | NULL | +--------------+-------------+

UNHEX()

UNHEX() 函数执行 HEX() 函数的逆运算,将参数中的每对字符视为十六进制数字,并将其转换为该数字表示的字符,返回值为二进制字符串。

查询示例:

SELECT UNHEX('54694442');

返回结果:

+--------------------------------------+ | UNHEX('54694442') | +--------------------------------------+ | 0x54694442 | +--------------------------------------+

UPPER()

UPPER() 函数将字符串转换为大写字母,此函数等价于 UCASE() 函数。

查询示例:

SELECT UCASE('bigdata') AS result_upper, UCASE(null) AS result_null;

返回结果:

+--------------+-------------+ | result_upper | result_null | +--------------+-------------+ | BIGDATA | NULL | +--------------+-------------+

WEIGHT_STRING()

WEIGHT_STRING() 函数返回字符串的权重(二进制字符),主要用于多字符集场景下的排序和比较操作。如果参数为 NULL,则返回 NULL。语法示例如下:

WEIGHT_STRING(str [AS {CHAR|BINARY}(N)])
  • str:字符串表达式。如果是非二进制字符串,例如 CHAR、VARCHAR 或 TEXT 值,则返回值包含该字符串的排序规则权重;如果是二进制字符串,例如 BINARY、VARBINARY 或 BLOB 值,则返回值与输入相同。
  • AS {CHAR|BINARY}(N):可选参数,用于指定输出结果的类型和长度。CHAR 表示字符数据类型,而 BINARY 表示二进制数据类型;N 指定输出的长度,取值为大于等于 1 的整数。

查询示例:

SET NAMES 'utf8mb4'; SELECT HEX(WEIGHT_STRING('ab' AS CHAR(3))) AS char_result, HEX(WEIGHT_STRING('ab' AS BINARY(3))) AS binary_result;

返回结果:

+-------------+---------------+ | char_result | binary_result | +-------------+---------------+ | 6162 | 616200 | +-------------+---------------+

不支持的函数

  • LOAD_FILE()
  • MATCH()
  • SOUNDEX()

正则函数与 MySQL 的兼容性

本节介绍 TiDB 中正则函数 REGEXP_INSTR()REGEXP_LIKE()REGEXP_REPLACE()REGEXP_SUBSTR() 与 MySQL 的兼容情况。

语法兼容性

MySQL 的实现使用的是 ICU (International Components for Unicode) 库,TiDB 的实现使用的是 RE2 库,两个库之间的语法差异可以查阅 ICU 文档RE2 文档

匹配模式 match_type 兼容性

TiDB 与 MySQL 在 match_type 上的差异:

  • TiDB 中 match_type 可选值为:"c""i""m""s"。MySQL 中 match_type 可选值为:"c""i""m""n""u"

  • TiDB 中 "s" 对应 MySQL 中的 "n",即 . 字符匹配行结束符。

    例如:MySQL 中 SELECT REGEXP_LIKE(a, b, "n") FROM t1; 在 TiDB 中需要修改为 SELECT REGEXP_LIKE(a, b, "s") FROM t1;

  • TiDB 不支持 match_type"u"

数据类型兼容性

TiDB 与 MySQL 在二进制字符串 (binary string) 数据类型上的差异:

  • MySQL 8.0.22 及以上版本中正则函数不支持二进制字符串,具体信息可查看 MySQL 文档。但在实际使用过程中,如果所有参数或者返回值的数据类型都是二进制字符串,则正则函数可以正常使用,否则报错。
  • TiDB 目前完全禁止使用二进制字符串,无论什么情况都会报错。

其它兼容性

  • TiDB 与 MySQL 在替换空字符串上存在差异,下面以 REGEXP_REPLACE("", "^$", "123") 为例:

    • MySQL 不会对空串进行替换,其结果为 ""
    • TiDB 会对空串进行替换,其结果为 "123"
  • TiDB 与 MySQL 在捕获组的关键字上存在差异。MySQL 的捕获组关键字为$,而 TiDB 的捕获组关键字为\\。此外,TiDB 只支持编号为 09 的捕获组。

    例如,以下 SQL 语句在 TiDB 中的返回结果为 ab

    SELECT REGEXP_REPLACE('abcd','(.*)(.{2})$','\\1') AS s;