
# 字符串函数
M-Compatibility提供字符串函数对字符串进行处理。
- 对于对字符串位置进行操作的函数，第一个位置的编号为1。
- 对于使用了长度作为参数的函数，非整数的参数将四舍五入到最接近的整数。
- 如果数据库字符集是SQL_ASCII，数据库将把字节值0\~127根据ASCII标准解释，而字节值128\~255则当作无法解析的字符。如果设置为SQL_ASCII，数据库将无法转换或者校验非ASCII字符，导致CHAR_LENGTH、FIND_IN_SET、LEFT、LOWER、REVERSE、RIGHT、STRCMP及TRIM等字符串函数产生未预期的结果。如果使用了任意非ASCII数据，都不建议将数据库的字符集设置为SQL_ASCII。
#### ASCII
ASCII(str)
描述：返回字符串str最左侧字符的ASCII码值，str为空字符串时返回0，str为NULL时返回NULL。
返回值类型：INT
示例：
```
m_db=# SELECT ASCII('');
 ascii 
-------
     0
(1 row)
m_db=# SELECT ASCII('abc');
 ascii 
-------
    97
(1 row)
m_db=# SELECT ASCII(NULL);
 ascii 
-------
(1 row)
```
#### BIT_LENGTH
BIT_LENGTH(str)
描述：返回字符串str的比特位长度。
返回值类型：BIGINT
示例：
```
m_db=# SELECT BIT_LENGTH('text');
 bit_length 
------------
         32
(1 row)
```
 #### CHAR_LENGTH
CHAR_LENGTH(str)
描述：返回字符串str包含的字符数，多字节的字符会被计为1个字符。例如，输入2个2字节的字符，LENGTH()返回4，而CHAR_LENGTH()返回2。
返回值类型：BIGINT
示例：
```
m_db=# SELECT CHAR_LENGTH('text');
 char_length 
-------------
           4
(1 row)
```
#### CHARACTER_LENGTH
CHARACTER_LENGTH(str)
描述：与[CHAR_LENGTH]功能、用法相同。
返回值类型：BIGINT
示例：
```
m_db=# SELECT CHARACTER_LENGTH('text');
 character_length 
------------------
                4
(1 row)
```
#### CONCAT
CONCAT(str1, str2, ..., strN)
描述：按入参顺序将N个字符串拼接并返回拼接后的字符串。如果有一个字符串为NULL，则返回NULL。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT CONCAT('hello', 'world', '!');
   concat    
-------------
 helloworld!
(1 row)
m_db=# SELECT CONCAT('hello', NULL, '!');
 concat 
--------
(1 row)
```
#### CONCAT_WS
CONCAT_WS(separator, str1, str2, ..., strN)
描述：把N个字符串按顺序进行拼接，相邻字符串使用separator进行分割。当separator为NULL时，返回NULL。当待拼接的字符串为NULL时，则忽略NULL。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT CONCAT_WS(',', 'hello', NULL, 'world', '!');
   concat_ws   
---------------
 hello,world,!
(1 row)
m_db=# SELECT CONCAT_WS(NULL, 'hello', NULL, 'world', '!');
 concat_ws 
-----------
(1 row)
```
#### FIELD
FIELD(str, str1, str2, str3, ...)
描述：field函数返回str在{str, str1, str2, str3, ...}列表中的位置。从1开始递增，返回0表示str不在{str, str1, str2, str3, ...}列表中。
返回值类型：BIGINT
- 如果str为NULL或者不在{str, str1, str2, str3, ...}列表时，直接返回0。
- 函数入参全部为数字时，按照数字进行比较；入参全部为非数字类型时，按照字符串进行比较；入参存在数字和非数字混合时，按照DOUBLE类型进行比较。
 
示例：
```
m_db=# SELECT FIELD(1,2,1);
 field 
------
     2
(1 row)
m_db=# SELECT FIELD('a','b','a');
 field 
------
     2
(1 row)
m_db=# SELECT FIELD('a',1,'b','a');
WARNING:  Truncated incorrect double value: 'a'
CONTEXT:  referenced column: field
WARNING:  Truncated incorrect double value: 'b'
CONTEXT:  referenced column: field
 field
-------
     2
(1 row)
```
#### FIND_IN_SET
FIND_IN_SET(str, strlist)
描述：返回字符串str在字符串列表strlist中的位置，从1开始递增。字符串列表strlist是1个包含若干个子字符串的字符串，各个子字符串之间使用逗号,进行分隔。
返回值类型：INT
- 如果strlist中不包含str，返回0。
- 如果str或strlist为NULL，则返回NULL。
- 如果str中包含逗号，则返回0。
 
示例：
```
m_db=# SELECT FIND_IN_SET('e', 'a,b,c;d,e');
 find_in_set 
-------------
           4
(1 row)
m_db=# SELECT FIND_IN_SET('a,', 'a,b,c;d,e');
 find_in_set 
-------------
           0
(1 row)
m_db=# SELECT FIND_IN_SET(NULL, 'a,b,c;d,e');
 find_in_set 
-------------
(1 row)
```
 #### HEX
- HEX(str) 描述：将字符串str转换为十六进制字符串，str中的每个字符的每个字节都转换为两个十六进制数字，其逆运算为[UNHEX]。
  返回值类型：TEXT
  示例：
  ```
  m_db=# SELECT HEX('abc'), UNHEX(HEX('abc'));
    hex   | unhex 
  --------+-------
   616263 | abc
  (1 row)
  ```
  
- HEX(N) 描述：将数字N转换为十六进制字符串。
  返回值类型：TEXT
  示例：
  ```
  m_db=# SELECT HEX(255);
   hex 
  -----
   FF
  (1 row)
  ```
  
 
 #### LCASE
LCASE(str)
描述：将字符串中的大写字符转换为小写字母。LCASE与[LOWER]功能、用法一致。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT LCASE('Hello,world!');
    lcase     
--------------
 hello,world!
(1 row)
```
#### LEFT
LEFT(str, len)
描述：返回字符串str最左侧的len个字符，如果str或len为NULL，返回NULL。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT LEFT('abcdef', 3);
 left 
------
 abc
(1 row)
m_db=# SELECT LEFT('abcdef', NULL);
 left 
------
(1 row)
m_db=# SELECT LEFT('abcdef', 11);
  left  
--------
 abcdef
(1 row)
```
#### LENGTH
LENGTH(str)
描述：返回字符串str包含的字节数，多字节的字符会被计为多个字节。例如，输入2个2字节的字符，LENGTH()返回4，而CHAR_LENGTH()返回2。
返回值类型：BIGINT
示例：
```
m_db=# SELECT LENGTH('text');
 char_length 
-------------
           4
(1 row)
```
 #### LOWER
LOWER(str)
描述：将字符串中的大写字母转换为小写字母。LOWER的功能、用法和[LCASE]一致。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT LOWER('Hello,world!');
    lower     
--------------
 hello,world!
(1 row)
```
#### LPAD
LPAD(str, len, padstr)
描述：使用字符串padstr从左侧填充字符串str，直到长度为len。返回值的长度受GUC参数max_allowed_packet的影响，最大取值为Min(max_allowed_packet/函数返回值字符集单字符最大长度, 1073741819)。
参数：具体说明如[表1]所示。
 表1LPAD参数说明 
| 参数     | 类型   | 描述        |
|:---|:---|:---|
| str    | TEXT | 待被填充的字符串  |
| len    | INT  | 填充后字符串的长度 |
| padstr | TEXT | 用于填充的字符串  |
   
返回值类型：TEXT/LONGBLOB
- 如果str长度大于len，则返回str左侧的len个字符。
- 如果str、len、padstr中有一个为NULL，则返回NULL。
- 如果len为负数，则返回NULL。
示例：
```
m_db=# SELECT LPAD('hello', 10, 'abc');
    lpad    
------------
 abcabhello
(1 row)
m_db=# SELECT LPAD('hello', 3, 'abc');
 lpad 
------
 hel
(1 row)
m_db=# SELECT LPAD('hello', 10, NULL);
 lpad 
------
(1 row)
m_db=# SELECT LPAD('hello', -10, 'abc');
 lpad 
------
(1 row)
```
#### LTRIM
LTRIM(str)
描述：删除字符串str左侧的空格。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT LTRIM('  hello   ');
  ltrim   
----------
 hello   
(1 row)
```
#### REPEAT
REPEAT(str, count)
描述：返回字符串str重复count次组成的字符串。如果count小于等于0，返回NULL。如果str或者count为NULL，返回NULL。返回值的长度受GUC参数max_allowed_packet的影响，最大取值为Min(max_allowed_packet, 1073741819)。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT REPEAT('abc', 3);
  repeat   
-----------
 abcabcabc
(1 row)
m_db=# SELECT REPEAT('abc', NULL);
 repeat 
--------
(1 row)
m_db=# SELECT REPEAT('abc', -1);
 repeat 
--------
(1 row)
```
#### REPLACE
REPLACE(str, from_str, to_str)
描述：使用字符串to_str替换字符串str中的字符串from_str，替换时区分大小写。当有任意一个参数为NULL时，返回NULL。返回值的长度受GUC参数max_allowed_packet的影响，最大取值为Min(max_allowed_packet, 1073741819)。
参数：具体说明如[表2]所示。
 表2REPLACE参数说明 
| 参数       | 类型   | 描述       |
|:---|:---|:---|
| str      | TEXT | 待被替换的字符串 |
| from_str | TEXT | 查找目标     |
| to_str   | TEXT | 替换成      |
   
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT REPLACE('abc,efg,hijk,abcde,dabc,e', 'abc', 'xyz');
          replace          
---------------------------
 xyz,efg,hijk,xyzde,dxyz,e
(1 row)
m_db=# SELECT REPLACE('abc,efg,hijk,abcde,dabc,e', NULL, 'xyz');
 replace 
---------
(1 row)
```
#### REVERSE
REVERSE(str)
描述：返回字符串str的倒序排列。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT REVERSE('abcd');
 reverse 
---------
 dcba
(1 row)
```
#### RIGHT
RIGHT(str, len)
描述：返回字符串str最右边len个字符，如果str或len为NULL，则返回NULL。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT RIGHT('abcdef', 4);
 right 
-------
 cdef
(1 row)
m_db=# SELECT RIGHT('abcdef', NULL);
 right 
-------
(1 row)
```
#### RPAD
RPAD(str, len, padstr)
描述：使用字符串padstr从右侧填充字符串str，直到长度为len。返回值的长度受GUC参数max_allowed_packet的影响，最大取值为Min(max_allowed_packet/函数返回值字符集单字符最大长度, 1073741819)。
参数：具体说明如[表3]所示。
 表3RPAD参数说明 
| 参数     | 类型   | 描述        |
|:---|:---|:---|
| str    | TEXT | 待被填充的字符串  |
| len    | INT  | 填充后字符串的长度 |
| padstr | TEXT | 用于填充的字符串  |
   
返回值类型：TEXT/LONGBLOB
- 如果str长度大于len，则返回str左侧的len个字符。
- 如果str、len、padstr中有一个为NULL，则返回NULL。
- 如果len为负数，则返回NULL。
示例：
```
m_db=#  SELECT RPAD('hello', 10, 'abc');
    rpad    
------------
 helloabcab
(1 row)
m_db=# SELECT RPAD('hello', 3, 'abc');
 rpad 
------
 hel
(1 row)
m_db=# SELECT RPAD('hello', 10, NULL);
 rpad 
------
(1 row)
m_db=# SELECT RPAD('hello', -10, 'abc');
 rpad 
------
(1 row)
```
#### RTRIM
RTRIM(str)
描述：删除字符串str右侧的空格。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT RTRIM('  hello   ');
  rtrim  
---------
   hello
(1 row)
```
#### SPACE
SPACE(N)
描述：返回由N个空格组成的字符串，如果N小于等于0，返回空字符串。返回值的长度受GUC参数max_allowed_packet的影响，最大取值为Min(max_allowed_packet, 1073741819)。
返回值类型：TEXT
示例：
```
m_db=# SELECT CONCAT('a', SPACE(6), 'b');
  concat  
----------
 a      b
(1 row)
m_db=# SELECT CONCAT('a', SPACE(-1), 'b');
 concat 
--------
 ab
(1 row)
```
#### STRCMP
STRCMP(str1, str2)
描述：比较str1与str2是否相同。
返回值类型：INT
- 如果 str1 等于 str2， STRCMP函数将返回 0。
- 如果 str1 小于 str2， STRCMP函数将返回 -1。
- 如果 str1 大于 str2， STRCMP函数将返回 1。
- 当任意个参数为 NULL 时， STRCMP函数将返回NULL。
示例：
```
m_db=# SELECT STRCMP('abc', 'abc');
 strcmp 
--------
      0
(1 row)
m_db=# SELECT STRCMP('abc1', 'abc');
 strcmp 
--------
      1
(1 row)
m_db=# SELECT STRCMP('abc', 'abc1');
 strcmp 
--------
     -1
(1 row)
m_db=# SELECT STRCMP('abc1', 'abc2');
 strcmp 
--------
     -1
(1 row)
m_db=# SELECT STRCMP('abc1', NULL);
 strcmp 
--------
(1 row)
```
 #### SUBSTR
SUBSTR函数有以下四种原型，各原型中str、pos以及len的含义一致。
- SUBSTR(str, pos)
- SUBSTR(str FROM pos)
- SUBSTR(str, pos, len)
- SUBSTR(str FROM pos FOR len)
- SUBSTR(str FOR len FROM pos)
- SUBSTR(str FOR len)
描述：返回str的子字符串，起始位置为pos，长度为len。不指定len时，返回的子字符串从pos位置开始，一直到str字符串的结尾。
- pos的位置从1开始计数。
- 参数中包含NULL时，返回NULL。
- pos为负数时，从str尾部向头部倒序确定起始位置。
- len小于等于0、pos的位置为0、pos的位置越界时，返回空字符串。
参数：具体说明如[表4]所示。
 表4SUBSTR参数说明 
| 参数  | 类型   | 描述       |
|:---|:---|:---|
| str | TEXT | 待被截取的字符串 |
| pos | INT  | 起始位置     |
| len | INT  | 子字符串的长度  |
   
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT SUBSTR('abcdefg', 2, 3);
 substr 
--------
 bcd
(1 row)
m_db=# SELECT SUBSTR('abcdefg', NULL);
 substr 
--------
(1 row)
m_db=# SELECT SUBSTR('abcdefg', 2);
 substr 
--------
 bcdefg
(1 row)
m_db=# SELECT SUBSTR('abcdefg', -2, 3);
 substr 
--------
 fg
(1 row)
m_db=# SELECT SUBSTR('abcdefg', -2);
 substr 
--------
 fg
(1 row)
m_db=# SELECT SUBSTR('abcdefg', 0, 3);
 substr 
--------
(1 row)
```
#### SUBSTRING
SUBSTRING函数有以下四种原型，各原型中str、pos以及len的含义一致。
- SUBSTRING(str, pos)
- SUBSTRING(str FROM pos)
- SUBSTRING(str, pos, len)
- SUBSTRING(str FROM pos FOR len)
- SUBSTRING(str FOR len FROM pos)
- SUBSTRING(str FOR len)
描述：SUBSTRING与[SUBSTR]功能、用法一致。
参数：具体说明如[表5]所示。
 表5SUBSTRING参数说明 
| 参数  | 类型   | 描述       |
|:---|:---|:---|
| str | TEXT | 待被截取的字符串 |
| pos | INT  | 起始位置     |
| len | INT  | 子字符串的长度  |
   
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT SUBSTRING('abcdefg', 2, 3);
 substring 
-----------
 bcd
(1 row)
m_db=# SELECT SUBSTRING('abcdefg', NULL);
 substring 
-----------
(1 row)
m_db=# SELECT SUBSTRING('abcdefg', 2);
 substring 
-----------
 bcdefg
(1 row)
m_db=# SELECT SUBSTRING('abcdefg', -2, 3);
 substring 
-----------
 fg
(1 row)
m_db=# SELECT SUBSTRING('abcdefg', -2);
 substring 
-----------
 fg
(1 row)
m_db=# SELECT SUBSTRING('abcdefg', 0, 3);
 substring 
-----------
(1 row)
```
#### SUBSTRING_INDEX
SUBSTRING_INDEX(str, delim, count)
描述：使用分隔符delim和次数count确定字符串str中最终分隔符的位置，返回分最终隔符左侧（或右侧）的全部字符。匹配分隔符delim时区分大小写。
- 如果count为正数，从字符串的左侧开始计数，直到delim出现了count次，返回最终分隔符左侧的全部字符。
- 如果count为负数，从字符串的右侧开始计数，直到delim出现了\|count\|次，返回最终分隔符右侧的全部字符。
- 如果任意一个参数为NULL，返回NULL。
- 如果str或delim为空字符串，返回空字符串
- 如果count等于0，返回空字符串。
参数：具体说明如[表6]所示。
 表6SUBSTRING_INDEX参数说明 
| 参数    | 类型   | 描述       |
|:---|:---|:---|
| str   | TEXT | 待被截取的字符串 |
| delim | TEXT | 分隔符      |
| count | INT  | 分隔符出现的次数 |
   
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT SUBSTRING_INDEX('abc..def..ghi..jkl....', '..', 3);
 substring_index 
-----------------
 abc..def..ghi
(1 row)
m_db=# SELECT SUBSTRING_INDEX('abc..def..ghi..jkl....', '..', -3);
 substring_index 
-----------------
 jkl....
(1 row)
m_db=# SELECT SUBSTRING_INDEX('abc..def..ghi..jkl....', '..', NULL);
 substring_index 
-----------------
(1 row)
m_db=# SELECT SUBSTRING_INDEX('abc..def..ghi..jkl....', '..' ,0);
 substring_index 
-----------------
(1 row)
```
#### TRIM
TRIM(\[\[BOTH \| LEADING \| TRAILING\] \[remstr\] FROM\] str)
描述：删除字符串str中的所有前缀/后缀子字符串remstr，当任意一个参数为NULL时，返回NULL。匹配remstr时区分大小写。
- remstr：默认为空格。

- \[BOTH \| LEADING \| TRAILING\]：
  - BOTH：删除前缀和后缀；
  
  - LEADING：删除前缀；
  
  - TRAILING：删除后缀；
  
  - 默认为BOTH。
   
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT TRIM('   abc   ');
 trim 
------
 abc
(1 row)
m_db=# SELECT TRIM(TRAILING FROM '   abc   ');
  trim  
--------
    abc
(1 row)
m_db=# SELECT TRIM(BOTH 'xyz' FROM 'xyzxyabcxyzxy');
    trim    
------------
 xyabcxyzxy
(1 row)
```
 #### UCASE
UCASE(str)
描述：将字符串中的小写字母转换为大写字母。UCASE的功能、用法和[UPPER]一致。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT UCASE('Hello,world!');
    ucase     
--------------
 HELLO,WORLD!
(1 row)
```
 #### UNHEX
UNHEX(str)
描述：将字符串str中的每个字符解释为十六进制数字，将其转换为该数字表示的字节，返回二进制字符串，其逆运算为[HEX(str)]。str中的字符必须是合法的十六进制数字，如果参数包含任何非法的数字，则返回NULL。
返回值类型：LONGBLOB
示例：
```
m_db=# SELECT UNHEX(616263), HEX(UNHEX('616263'));
 unhex |  hex   
-------+--------
 abc   | 616263
(1 row)
```
 #### UPPER
UPPER(str)
描述：将字符串中的小写字母转换为大写字母。UPPER的功能、用法和[UCASE]一致。
返回值类型：TEXT/LONGBLOB
示例：
```
m_db=# SELECT UPPER('Hello,world!');
    upper     
--------------
 HELLO,WORLD!
(1 row)
```
