3.3.2.2. 转换为 GaussDB-Oracle
3.3.2.2.1. 时间日期函数
3.3.2.2.1.1. YEAR
- 语法
YEAR(date)
- 描述
- 该函数功能是返回日期的年份。
参数解释
参数 |
说明 |
---|---|
date |
指定日期。该参数可以为 text、timestamp 数据类型。 |
示例
-- 转换前MySQL SQL:
select year(20200101);
+----------------+
| year(20200101) |
+----------------+
| 2020 |
+----------------+
select year('200102');
+----------------+
| year('200102') |
+----------------+
| 2020 |
+----------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.year(20200101);
year
------
2020
SELECT unisql.year('200102');
year
------
2020
3.3.2.2.1.2. DAY
- 语法
DAY(date)
- 描述
- 该函数返回当前会话时区的当前日期
参数解释
参数 |
说明 |
---|---|
date |
指定日期。该参数可以为 text、timestamp 数据类型。 |
示例
-- 转换前MySQL SQL:
select day(20200101);
+---------------+
| day(20200101) |
+---------------+
| 1 |
+---------------+
select day('200102');
+---------------+
| day('200102') |
+---------------+
| 2 |
+---------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.day(20200101);
day
-----
1
SELECT unisql.day('200102');
day
-----
2
3.3.2.2.1.3. DAYOFWEEK
- 语法
DAYOFWEEK(time)
- 描述
- 该函数返回星期几
参数解释
参数 |
说明 |
---|---|
time |
指定日期。该参数可以为 text、timestamp 数据类型。 |
示例
-- 转换前MySQL SQL:
select dayofweek(20200101);
+---------------------+
| dayofweek(20200101) |
+---------------------+
| 4 |
+---------------------+
select dayofweek('200102');
+---------------------+
| dayofweek('200102') |
+---------------------+
| 5 |
+---------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.dayofweek(20200101)
dayofweek
-----------
5
SELECT unisql.dayofweek('200102')
dayofweek
-----------
4
3.3.2.2.1.4. WEEKOFYEAR
- 语法
WEEKOFYEAR(time)
- 描述
- 该函数返回当前的周数
参数解释
参数 |
说明 |
---|---|
time |
指定日期。该参数可以为 text、timestamp 数据类型。 |
示例
-- 转换前MySQL SQL:
select weekofyear(20200101);
+----------------------+
| weekofyear(20200101) |
+----------------------+
| 1 |
+----------------------+
select weekofyear('200102');
+----------------------+
| weekofyear('200102') |
+----------------------+
| 1 |
+----------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.weekofyear(20200101);
weekofyear
------------
1
SELECT unisql.weekofyear('200102');
weekofyear
------------
1
3.3.2.2.1.5. DATE_FORMAT
- 语法
DATE_FORMAT(time, format)
- 描述
- 按照指定的日期格式显示
参数解释
参数 |
说明 |
---|---|
time |
|
format |
日期显示格式,该参数为字符串类型,支持清单详见下表 |
序号 |
日期时间显示格式 |
含义 |
---|---|---|
1 |
%c |
月,数值 |
2 |
%d |
月的天,数值(00-31) |
3 |
%e |
月的天,数值(0-31) |
4 |
%f |
微秒 |
5 |
%H |
小时 (00-23) |
6 |
%h |
小时 (01-12) |
7 |
%I |
小时 (01-12) |
8 |
%i |
分钟,数值(00-59) |
9 |
%k |
小时 (0-23) |
10 |
%l |
小时 (1-12) |
11 |
%M |
月名 |
12 |
%m |
月,数值(00-12) |
13 |
%p |
AM 或 PM |
14 |
%r |
时间,12-小时(hh:mm:ss AM 或 PM) |
15 |
%S |
秒(00-59) |
16 |
%s |
秒(00-59) |
17 |
%T |
时间,24-小时(hh:mm:ss) |
18 |
%W |
星期名 |
19 |
%Y |
年,4位 |
20 |
%y |
年,2位 |
示例
-- 转换前MySQL SQL:
select date_format('2020-01-01 08:13:13', '%Y/%m/%d %h %i %s');
+---------------------------------------------------------+
| date_format('2020-01-01 08:13:13', '%Y/%m/%d %h %i %s') |
+---------------------------------------------------------+
| 2020/01/01 08 13 13 |
+---------------------------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.date_format('2020-01-01 08:13:13', 'YYYY/MM/DD HH MI SS');
date_format
---------------------
2020/01/01 08 13 13
3.3.2.2.1.6. STR_TO_DATE
- 语法
STR_TO_DATE(date, format)
- 描述
- 将字符串转换为时间值。这是 DATE_FORMAT() 函数的反函数
参数解释
参数 |
说明 |
---|---|
date |
指定日期时间,该参数为 text数据类型 |
format |
日期显示格式,支持清单详见DATA_FORMAT一节 |
警告
date的范围需要与format范围一致,例如date精确到秒,那么format也需要精确到秒
示例
-- 转换前Oracle SQL:
select str_to_date('2022/09/10 11,13,13', '%Y/%m/%d %h,%i,%s');
+---------------------------------------------------------+
| str_to_date('2022/09/10 11,13,13', '%Y/%m/%d %h,%i,%s') |
+---------------------------------------------------------+
| 2022-09-10 11:13:13 |
+---------------------------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT to_date('2022/09/10 11,13,13', 'YYYY/MM/DD HH,MI,SS');
to_date
---------------------
2022-09-10 11:13:13
3.3.2.2.1.7. FROM_UNIXTIME
- 语法
FROM_UNIXTIME (timestmap1 [, foramt])
- 描述
- 根据 UNIX 时间戳返回时间格式
参数解释
参数 |
说明 |
---|---|
timestmap1 |
UNIX 时间戳,该参数可以为字符串或整形数据类型。 |
format |
日期显示格式,支持清单详见DATA_FORMAT一节 |
示例
警告
第二个参数可选,如仅传入第一个参数,则默认时间格式为 %Y-%m-%d %h:%i:%s
-- 转换前MySQL SQL:
select from_unixtime(20220910);
+-------------------------+
| from_unixtime(20220910) |
+-------------------------+
| 1970-08-23 08:55:10 |
+-------------------------+
select from_unixtime(20220910, '%Y/%m/%d %h,%i,%s');
+----------------------------------------------+
| from_unixtime(20220910, '%Y/%m/%d %h,%i,%s') |
+----------------------------------------------+
| 1970/08/23 08,55,10 |
+----------------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.from_unixtime(20220910);
from_unixtime
---------------------
1970-08-23 08:55:10
SELECT unisql.from_unixtime(20220910, 'YYYY/MM/DD HH,MI,SS');
from_unixtime
---------------------
1970/08/23 08,55,10
3.3.2.2.1.8. UNIX_TIMESTAMP
- 语法
UNIX_TIMESTAMP ([timestmap1])
- 描述
- 根据 UNIX 时间戳返回时间格式
参数解释
参数 |
说明 |
---|---|
timestmap1 |
日期时间,该参数可以为字符串或timestamp数据类型。 |
示例
警告
函数入参可选,如果不传入参数,则默认返回当前linux系统时间的unix时间戳
当参数为空或者参数为now()时,转化为GAUSSDB_ORACLE的语法,查询的结果会有5位小数
注意将数据库的时区设置正确
-- 转换前MySQL SQL:
select UNIX_TIMESTAMP('2020-01-01 13:13:13');
+---------------------------------------+
| UNIX_TIMESTAMP('2020-01-01 13:13:13') |
+---------------------------------------+
| 1577855593 |
+---------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT extract(epoch FROM CAST('2020-01-01 13:13:13' AS timestamp with time zone));
date_part
------------
1577855593
-- 转换前MySQL SQL:
SELECT UNIX_TIMESTAMP(now());
+-----------------------+
| UNIX_TIMESTAMP(now()) |
+-----------------------+
| 1724059253 |
+-----------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT extract(epoch FROM CAST(now() AS timestamp with time zone));
date_part
------------------
1724059253.43542
3.3.2.2.1.9. DATE_ADD
- 语法
DATE_ADD (timestamp1, interval)
- 描述
- 用于将指定的时间间隔添加到日期或时间值上
参数解释
参数 |
说明 |
---|---|
timestmap1 |
日期时间,该参数可以为字符串或timestamp数据类型。 |
interval |
时间间隔,该参数为interval类型,支持清单:年(year)/月(month)/星期(week)/日(day) |
警告
和mysql的DATE_ADD不同,经统一sql转换执行GaussDB-Oracle的DATE_ADD查询结果返回的是timestamp;
示例
-- 转换前MySQL SQL:
select date_add('20200101', interval 1 day);
+--------------------------------------+
| date_add('20200101', interval 1 day) |
+--------------------------------------+
| 2020-01-02 |
+--------------------------------------+
select date_add('20200101', interval 1 week);
+---------------------------------------+
| date_add('20200101', interval 1 week) |
+---------------------------------------+
| 2020-01-08 |
+---------------------------------------+
select date_add('20200101', interval 2.6 day);
+---------------------------------------+
| date_add('20200101', interval 2.6 day)|
+---------------------------------------+
| 2020-01-04 |
+---------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.date_add('20200101', 1, 'day');
date_add
---------------------
2020-01-02 00:00:00
SELECT unisql.date_add('20200101', 1, 'week');
date_add
---------------------
2020-01-08 00:00:00
SELECT unisql.date_add('20200101', 2.6, 'day')
date_add
---------------------
2020-01-04 00:00:00
3.3.2.2.1.10. DATE_SUB
- 语法
DATE_SUB (timestamp1, interval)
- 描述
- 用于从指定的日期或时间值中减去一个时间间隔
参数解释
参数 |
说明 |
---|---|
timestmap1 |
日期时间,该参数可以为字符串或timestamp数据类型。 |
interval |
时间间隔,该参数为interval类型,支持清单:年(year)/月(month)/星期(week)/日(day) |
警告
和mysql的DATE_SUB不同,经统一sql转换执行GaussDB-Oracle的DATE_SUB查询结果返回的是timestamp;
示例
-- 转换前MySQL SQL:
select date_sub('20200101', interval 1 day);
+--------------------------------------+
| date_sub('20200101', interval 1 day) |
+--------------------------------------+
| 2019-12-31 |
+--------------------------------------+
select date_sub('20200101', interval 1 week);
+---------------------------------------+
| date_sub('20200101', interval 1 week) |
+---------------------------------------+
| 2019-12-25 |
+---------------------------------------+
select date_sub('20200101', interval 2.6 day);
+-------------------------------------------+
| date_sub('20200101', interval 2.6 day) |
+-------------------------------------------+
| 2019-12-29 |
+-------------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.date_sub('20200101', 1, 'day');
date_sub
---------------------
2019-12-31 00:00:00
SELECT unisql.date_sub('20200101', 1, 'week');
date_sub
---------------------
2019-12-25 00:00:00
SELECT unisql.date_sub('20200101', 2.6, 'day');
date_sub
---------------------
2019-12-29 00:00:00
3.3.2.2.1.11. CURDATE
- 语法
CURDATE ()
- 描述
- 以 %y-%m-%d 格式返回当前日期
示例
-- 转换前MySQL SQL:
select curdate();
+------------+
| curdate() |
+------------+
| 2024-08-12 |
+------------+
-- 转换后GaussDB-Oracle SQL:
SELECT current_date;
timestamp
---------------------
2024-08-12 12:34:43
3.3.2.2.1.12. SYSDATE
- 语法
SYSDATE ()
- 描述
- 返回此函数执行时的时间,受当前时区设置影响。
示例
-- 转换前MySQL SQL:
select sysdate();
+---------------------+
| sysdate() |
+---------------------+
| 2024-08-12 08:56:34 |
+---------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT sysdate;
sysdate
---------------------
2024-08-12 12:35:14
3.3.2.2.1.13. TIMESTAMP
- 语法
TIMESTAMP()
- 描述
- 将日期和时间转换成一个标准的时间戳格式,也可以用于将日期和时间的字符串表示形式转换为时间戳。目前仅适配函数的参数为now();
示例
-- 转换前MySQL SQL:
select timestamp(now()) from dual;
timestamp(now()) |
-----------------------+
2024-08-23 13:20:27.000|
-- 转换后GaussDB-Oracle SQL:
SELECT CAST(now() AS timestamp(0)) FROM sys_dummy
now |
-----------------------+
2024-08-23 13:20:27.000|
3.3.2.2.1.14. CURRENT_TIME
- 语法
CURRENT_TIME
- 描述
- 用于获取当前时间,精确到秒
警告
当前转换结果范围为年月日时分秒,mysql为时分秒,这个点不一致
示例
-- 转换前MySQL SQL:
select CURRENT_TIME;
+--------------------+
| CURRENT_TIME |
+--------------------+
| 17:08:05 |
+--------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT sysdate;
sysdate
---------------------------
2024-08-23 17:10:22
3.3.2.2.2. 条件函数
3.3.2.2.2.1. IFNULL
- 语法
IFNULL (anycompatible1, anycompatible2)
- 描述
- 根据参数是否为空,返回相应的值。
参数解释
参数 |
说明 |
---|---|
anycompatible1 |
判断该参数是否为null,如果不为null,则返回该参数 |
anycompatible2 |
判断第一个参数是否为null,如果为null,则返回该参数 |
示例
-- 转换前MySQL SQL:
select ifnull(1, 15);
+---------------+
| ifnull(1, 15) |
+---------------+
| 1 |
+---------------+
select ifnull(null, 15);
+------------------+
| ifnull(null, 15) |
+------------------+
| 15 |
+------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT nvl(1, 15);
nvl
-----
1
SELECT nvl(NULL, 15);
nvl
-----
15
3.3.2.2.2.2. IF
- 语法
IF (expr1, expr2, expr3)
- 描述
- 如果第一个参数为TRUE,则返回第二个参数,否则返回第三个参数。
参数解释
参数 |
说明 |
---|---|
expr1 |
判断该参数是否为true |
expr2 |
如果expr1为true,则返回expr2 |
expr3 |
如果expr1不为true,则返回expr3 |
警告
mysql中,null和空字符串不相等,而gaussdb_oracle中,null和空字符串相等都是null。
gaussdb_oracle中null相关表达式操作会返回null
expr1中null相关表达式操作会返回null
示例
-- 转换前MySQL SQL:
SELECT IF(1>2,2,3);
+-------------+
| IF(1>2,2,3) |
+-------------+
| 3 |
+-------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.IF(1>2, 2, 3)
if|
--+
3|
3.3.2.2.2.3. ISNULL
- 语法
ISNULL (anycompatible)
- 描述
- 判断是否为null,为null则返回1,非null返回0
参数解释
参数 |
说明 |
---|---|
anycompatible |
判断该参数是否为null |
示例
create table t1(id text);
insert into t1 values(123), (null), ('a');
-- 转换前MySQL SQL:
select isnull(id) from t1;
+------------+
| isnull(id) |
+------------+
| 0 |
| 1 |
| 0 |
+------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.isnull(id) FROM t1;
isnull
------
0
1
0
3.3.2.2.3. 字符串函数
3.3.2.2.3.1. LOCATE
- 语法
LOCATE (substr, str [, position])
- 描述
- 返回子字符串第一次出现的位置。
参数解释
参数 |
说明 |
---|---|
substr |
需要查找的字串,该参数为字符串类型 |
str |
需要被查找的父串,该参数为字符串类型 |
position |
从父串中指定位置开始查找子串(初始值为1),该参数为整形类型,可选参数,不填时默认从父串启示位置开始查找子串 |
示例
-- 转换前MySQL SQL:
SELECT LOCATE('bar', 'foobarbar', 5);
+-------------------------------+
| LOCATE('bar', 'foobarbar', 5) |
+-------------------------------+
| 7 |
+-------------------------------+
SELECT LOCATE('bar', 'foobarbar', 1);
+-------------------------------+
| LOCATE('bar', 'foobarbar', 1) |
+-------------------------------+
| 4 |
+-------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT instr('foobarbar', 'bar', 5);
instr
-------
7
SELECT instr('foobarbar', 'bar', 1);
instr
-------
4
3.3.2.2.3.2. CONVERT
- 语法
CONVERT (expr, type)
CONVERT (column_name using encoding_format)
- 描述
- 将expr转换为指定的数据类型。将列数据转换为指定的编码类型。
参数解释
参数 |
说明 |
---|---|
expr |
需要被转换类型的值。 |
type |
指定转换的类型,该参数支持singed、unsigned、decimal、float、date、char 数据类型 |
column_name |
列名 |
encoding_format |
指定的编码格式,目前支持utf8,gbk |
警告
MySQL与Gaussdb对于char类型在通过cast转换时行为不一致: MySQL类型转换时认为char类型即表示为长字符串类型,而在GaussDB类型转换中认为char类型仅表示单字节字符;
使用cast将值转为singed,值如果是字符那么必须是整型;
使用CONVERT将值转为unsinged,值必须是正整型、正整型字符串和正浮点型,且其值小于等于2^64 - 1;如果值为负数、浮点数字符串和值超过2^64 - 1,源库和目标库表现不一致。
使用CONVERT将列数据转换为指定的编码类型,不支持列的类型有bit、bytea
注意
MariaDB CONVERT
函数与 GaussDB-Oracle convert_to
函数的差异
功能差异:
MariaDB
CONVERT
:将字符串表达式按照指定的字符集进行编码转换,结果仍然是字符串类型。GaussDB-Oracle
convert_to
:将文本数据从数据库编码转换为指定编码的二进制表示形式(bytea
类型)。
函数用法:
MariaDB:
CONVERT(表达式 USING 字符集名称)
例如:CONVERT(groupName USING gbk)
GaussDB-Oracle:
convert_to(源字符串, 目标字符集名称)
例如:convert_to(groupName, 'gbk')
源字符串
:要转换的文本,可以是text
、varchar
等字符类型。目标字符集名称
:希望转换成的编码格式,例如'gbk'
。结果:返回一个字节数组(
bytea
),表示源字符串以目标字符集编码后的二进制内容(以十六进制显示)。
支持的字符集:
共同支持:
utf8
、gbk
和utf8mb3
。自动转换:
utf8mb3
会自动转换为utf8
。不支持:
utf16
、gb18030
等其他字符集,在 统一SQL 解析时会报错。
限制与注意事项:
类型限制: 无法直接转换
bit
、bytea
、XMLTYPE
、json
等非text
类型的字段。数据差异: 暂不考虑因数据库本身数据差异导致的转换问题,例如:
日期类型的格式差异,date类型,在mariadb中存储日期,比如2024-01-01,在gaussdb oracle中存储日期补充时分秒,2024-01-01 00:00:00
char
类型的自动补齐NULL
与空字符串''
的差异,在 mariadb 中,NULL 和空字符串是不同的;而在 GaussDB-Oracle 中,这两者被视为相等,结果均为NULL
排序差异: MariaDB 默认的 Collation 可能导致排序不符合预期。对于
gbk
字符集,建议显式指定COLLATE gbk_bin
,它会按照字节值的十六进制表示进行比较。数值类型转换差异:
MariaDB 中
CONVERT(数值列 USING utf8)
会将数值列隐式转换为字符串类型(如CHAR
),并且空值(NULL
)会被视为最小字符序列参与排序。GaussDB-Oracle 中
convert_to(数值列, 'utf8')
直接处理数值类型时,二进制转换结果可能与字符串排序规则不一致,并且 GaussDB-Oracle 默认将NULL
排在最后。
-- 转换前MySQL SQL:
select convert(123, signed);
+----------------------+
| convert(123, signed) |
+----------------------+
| 123 |
+----------------------+
select convert('this is a testdb', char);
+-----------------------------------+
| convert('this is a testdb', char) |
+-----------------------------------+
| this is a testdb |
+-----------------------------------+
SELECT CONVERT(CAST('2024-08-12' AS CHAR), char) AS converted_result;
+------------------+
| converted_result |
+------------------+
| 2024-08-12 |
+------------------+
SELECT CONVERT(CAST('2024-08-12' AS CHAR(20)), char) AS converted_result;
+------------------+
| converted_result |
+------------------+
| 2024-08-12 |
+------------------+
SELECT convert('1.005',double);
convert('1.005',double)|
-----------------------+
1.005|
SELECT convert('312',UNSIGNED),convert(0.123,UNSIGNED),convert('18446744073709551615',UNSIGNED);
convert('312',UNSIGNED)|convert(0.123,UNSIGNED)|convert('18446744073709551615',UNSIGNED)|
-----------------------+-----------------------+----------------------------------------+
312| 0| 18446744073709551615|
WITH cte AS (
SELECT 1 AS id, 'unisql_test1' AS unisql_name
UNION ALL
SELECT 2 AS id, 'unisql_test2' AS unisql_name
UNION ALL
SELECT 3 AS id, 'unisql_test3' AS unisql_name
UNION ALL
SELECT 4 AS id, 'unisql_test4' AS unisql_name
)
SELECT id, unisql_name
FROM cte
ORDER BY CONVERT(unisql_name USING gbk);
id|unisql_name |
--+------------+
1|unisql_test1|
2|unisql_test2|
3|unisql_test3|
4|unisql_test4|
-- 转换后GaussDB-Oracle SQL:
SELECT CAST(123 AS signed);
int8
------
123
SELECT CAST('this is a testdb' AS varchar);
varchar
------------------
this is a testdb
SELECT CAST(CAST('2024-08-12' AS char) AS varchar) AS converted_result;
converted_result
------------------
2
SELECT CAST(CAST('2024-08-12' AS char(20)) AS varchar) AS converted_result;
converted_result
------------------
2024-08-12
SELECT CAST('1.005' AS number)
numeric|
-------+
1.005|
SELECT CAST('312' AS decimal(20,0)),CAST(0.123 AS decimal(20,0)),CAST('18446744073709551615' AS decimal(20,0))
numeric|numeric|numeric |
-------+-------+--------------------+
312| 0|18446744073709551615|
WITH RECURSIVE cte AS
(SELECT 1 AS id,'unisql_test1' AS unisql_name
UNION ALL SELECT 2 AS id,'unisql_test2' AS unisql_name
UNION ALL SELECT 3 AS id,'unisql_test3' AS unisql_name
UNION ALL SELECT 4 AS id,'unisql_test4' AS unisql_name)
SELECT id,unisql_name FROM cte ORDER BY convert_to(unisql_name, 'gbk')
id|unisql_name |
--+------------+
1|unisql_test1|
2|unisql_test2|
3|unisql_test3|
4|unisql_test4|
-- mariadb CONVERT(表达式 USING 字符集名称) 与 gaussdb oracle中convert_to(源字符串, 目标字符集名称) 差异
-- 转换前 CONVERT(expr USING transcoding_name)
SELECT CONVERT('abc' USING utf8);
SELECT CONVERT('abc' USING utf8mb3);
SELECT convert_to('测试数据', 'utf8') AS utf8_result;
SELECT CONVERT('测试数据' USING utf16) AS utf16_result; -- 统一 SQL 解析报错: Unknown character set: 'utf16'
SELECT CONVERT(12345 USING utf8) AS number_convert;
SELECT CONVERT(NULL USING utf8) AS null_convert;
SELECT CONVERT('' USING utf8) AS empty_convert;
-- 转换后 convert_to(source text, dest_encoding name)
SELECT convert_to('abc', 'utf8');
SELECT convert_to('abc', 'utf8');
SELECT convert_to('测试数据', 'utf8') AS utf8_result;
SELECT convert_to(12345, 'utf8') AS number_convert;
SELECT convert_to(NULL, 'utf8') AS null_convert;
SELECT convert_to('', 'utf8') AS empty_convert;
-- 创建测试表
CREATE TABLE test_convert (
id INT PRIMARY KEY,
num INT, -- 数值类型测试
txt VARCHAR(100), -- 字符串类型测试
dt DATE -- 日期类型测试
);
-- 插入测试数据(涵盖中英文、空值、边界值)
INSERT INTO test_convert VALUES
(1, 100, 'Hello', '2024-01-01'),
(2, 200, '你好', '2024-02-02'),
(3, 300, 'abc测试', NULL),
(4, NULL, '', '2024-04-04'),
(5, 500, NULL, '2024-05-05');
-- 数值列排序测试(UTF8)
-- 源库 SQL
SELECT num, id FROM test_convert ORDER BY CONVERT(num USING utf8);
-- 查询的结果
num | id |
--- + -- +
| 4 |
100 | 1 |
200 | 2 |
300 | 3 |
500 | 5 |
-- 目标库转换 SQL
SELECT id FROM test_convert ORDER BY convert_to(num, 'utf8');
-- 查询的结果
num | id |
--- + -- +
100 | 1 |
200 | 2 |
300 | 3 |
500 | 5 |
| 4 |
-- 字符串列排序测试(GBK)
-- 源库 SQL
SELECT txt, id FROM test_convert ORDER BY CONVERT(txt USING gbk);
+-----------+----+
| txt | id |
+-----------+----+
| NULL | 5 |
| | 4 |
| abc测试 | 3 |
| Hello | 1 |
| 你好 | 2 |
+-----------+----+
-- MariaDB 中,NULL → 空字符串 → Hello → abc测试 → 你好,使用 GBK 字符集,MariaDB 默认的 Collation 可能导致排序不符合预期,需显式指定 COLLATE gbk_bin
SELECT txt, id FROM test_convert ORDER BY CONVERT(txt USING gbk) COLLATE gbk_bin;
+-----------+----+
| txt | id |
+-----------+----+
| NULL | 5 |
| | 4 |
| Hello | 1 |
| abc测试 | 3 |
| 你好 | 2 |
-- 目标库转换 SQL
SELECT txt, id FROM test_convert ORDER BY convert_to(txt, 'gbk');
-- 查询结果
txt | id |
--------- + -- +
Hello | 1 |
abc测试 | 3 |
你好 | 2 |
| 4 |
| 5 |
-- 日期列排序测试(显式转换字符集)
-- 源库 SQL
SELECT dt, id FROM test_convert ORDER BY CONVERT(dt USING utf8);
+------------+----+
| dt | id |
+------------+----+
| NULL | 3 |
| 2024-01-01 | 1 |
| 2024-02-02 | 2 |
| 2024-04-04 | 4 |
| 2024-05-05 | 5 |
+------------+----+
-- 目标库转换 SQL
SELECT dt, id FROM test_convert ORDER BY convert_to(dt, 'utf8');
dt | id
---------------------+----
2024-01-01 00:00:00 | 1
2024-02-02 00:00:00 | 2
2024-04-04 00:00:00 | 4
2024-05-05 00:00:00 | 5
| 3
3.3.2.2.3.3. CAST
- 语法
CAST (expr AS type)
- 描述
- 将expr转换为指定的数据类型。
参数解释
参数 |
说明 |
---|---|
expr |
需要被转换类型的值。 |
type |
指定转换的类型,该参数支持unsigned数据类型 |
警告
使用CAST将值转为unsinged,值必须是正整型、正整型字符串和正浮点型,且其值小于等于2^64 - 1;如果值为负数、浮点数字符串和值超过2^64 - 1,源库和目标库表现不一致。
示例
-- 转换前MySQL SQL:
SELECT cast('312' as UNSIGNED),cast(0.123 as UNSIGNED),cast('18446744073709551615' as UNSIGNED);
cast('312' as UNSIGNED)|cast(0.123 as UNSIGNED)|cast('18446744073709551615' as UNSIGNED)|
-----------------------+-----------------------+----------------------------------------+
312| 0| 18446744073709551615|
-- 转换后GaussDB-Oracle SQL:
SELECT CAST('312' AS decimal(20,0)),CAST(0.123 AS decimal(20,0)),CAST('18446744073709551615' AS decimal(20,0))
numeric|numeric|numeric |
-------+-------+--------------------+
312| 0|18446744073709551615|
3.3.2.2.3.4. CONCAT
- 语法
CONCAT (str1, str2, ...)
- 描述
- 将入参字符串拼接在一起。
参数解释
参数 |
说明 |
---|---|
str |
需要拼接的字符串,该参数为字符串数据类型 |
示例
-- 转换前MySQL SQL:
select concat('123', 'abcAA', '你好');
+--------------------------------+
| concat('123', 'abcAA', '你好') |
+--------------------------------+
| 123abcAA你好 |
+--------------------------------+
select concat('123abc');
+------------------+
| concat('123abc') |
+------------------+
| 123abc |
+------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT concat('123', 'abcAA', '你好');
concat
--------------
123abcAA你好
SELECT concat('123abc');
concat
--------
123abc
3.3.2.2.3.5. GROUP_CONCAT
- 语法
GROUP_CONCAT([DISTINCT] column_name… [ORDER BY ASC/DESC column_name] [Separator sep_str])
- 描述
- 将来自多个行的列值组合成一个单独的字符串,每个值之间可以用分隔符隔开。
参数解释
参数 |
说明 |
---|---|
column_name |
需要拼接的字符串列,该参数为字符串数据类型 |
sep_str |
分割标识符 |
警告
和 group by 使用时拼接顺序和oracle库中不完全一致; 行展示顺序不一致,建议使用该函数时根据列名进行排序; 存在表达式计算时精度、标度和oracle不完全一致; 暂时不支持和keep、over联合使用; 和聚合函数使用时不支持嵌套使用。
示例
create table test_group_concat(id int, age int);
INSERT INTO test_group_concat (id, age) VALUES (1, 20);
INSERT INTO test_group_concat (id, age) VALUES (1, 20);
INSERT INTO test_group_concat (id, age) VALUES (1, 10);
INSERT INTO test_group_concat (id, age) VALUES (3, 30);
INSERT INTO test_group_concat (id, age) VALUES (3, 40);
INSERT INTO test_group_concat (id, age) VALUES (3, 40);
INSERT INTO test_group_concat (id, age) VALUES (4, 50);
INSERT INTO test_group_concat (id, age) VALUES (4, 60);
-- 转换前MySQL SQL:
select id, group_concat(age) from test_group_concat group by id;
+----+-------------------+
| id | group_concat(age) |
+----+-------------------+
| 1 | 20,20,10 |
| 3 | 30,40,40 |
| 4 | 50,60 |
+----+-------------------+
select group_concat(age) from test_group_concat;
+-------------------------+
| group_concat(age) |
+-------------------------+
| 20,20,10,30,40,40,50,60 |
+-------------------------+
select group_concat(distinct age order by age desc separator ':') from test_group_concat;
+------------------------------------------------------------+
| group_concat(distinct age order by age desc separator ':') |
+------------------------------------------------------------+
| 60:50:40:30:20:10 |
+------------------------------------------------------------+
-- 转换后GaussDB-Oracle SQL:
select id, group_concat(age) from test_group_concat group by id;
id | group_concat
----+--------------
1 | 20,20,10
4 | 50,60
3 | 30,40,40
SELECT string_agg(age, ',') FROM test_group_concat;
string_agg
-------------------------
20,20,10,30,40,40,50,60
SELECT string_agg(DISTINCT age, ':') FROM test_group_concat;
string_agg
-------------------
10:20:30:40:50:60
3.3.2.2.4. 其他函数
3.3.2.2.4.1. COMPRESS
- 语法
compress (plaintext)
- 描述
- 压缩字符串并返回二进制数据。
参数解释
参数 |
说明 |
---|---|
plaintext |
需要压缩的明文,该参数为字符串类型 |
示例
-- 转换前MySQL SQL:
select compress('123abc你好');
+----------------------------------------------------+
| compress('123abc你好') |
+----------------------------------------------------+
| 0x0C000000789C3334324E4C4A7EB277C1D3A57B011FE90645 |
+----------------------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.compress('123abc你好');
compress
--------------------------------
123abc\344\275\240\345\245\275
3.3.2.2.4.2. UNCOMPRESS
- 语法
uncompress (ciphertext)
- 描述
- 解压由compress()函数压缩的二进制数据,并恢复原始字符串。
参数解释
参数 |
说明 |
---|---|
ciphertext |
需要解压缩的密文,该参数为二进制类型bytea。 |
示例
-- 转换前MySQL SQL:
select uncompress(compress('123abc你好'));
+------------------------------------+
| uncompress(compress('123abc你好')) |
+------------------------------------+
| 0x313233616263E4BDA0E5A5BD |
+------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.uncompress(unisql.compress('123abc你好'));
uncompress
--------------------------------
123abc\344\275\240\345\245\275
3.3.2.2.4.3. LAST_INSERT_ID
- 语法
LAST_INSERT_ID ()
- 描述
- 用于获取最后一次插入操作中自动生成的自增类型值。
示例
-- 转换前MySQL SQL:
create table t1(id int primary key auto_increment, co1 int);
insert into t1(co1) values(12), (23);
select * from t1;
+-----+-----+
| id | co1 |
+-----+-----+
|| 1 || 12 |
|| 2 || 23 |
+-----+-----+
select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
-- 转换后GaussDB-Oracle SQL:
CREATE TABLE t1 (id serial PRIMARY KEY,co1 int);
insert into t1(co1) values(12), (23);
select * from t1;
id | co1
----+-----
1 | 12
2 | 23
SELECT lastval();
lastval
---------
2
警告
mysql中的last_insert_id函数在单行或者多行插入时只返回第一行id,gaussdb中使用lastval函数替换last_insert_id且始终返回最后一次序列的值,所以仅在单行数据插入时mysql和gaussdb_oracle保持一致。
3.3.2.2.4.4. UUID
- 语法
UUID ()
- 描述
- 用于生成一个唯一的标识符(UUID),保证在空间和时间上的唯一性
示例
-- 转换前MySQL SQL:
select uuid();
+--------------------------------------+
| uuid() |
+--------------------------------------+
| 664c5710-5ba0-11ef-a608-005056c00001 |
+--------------------------------------+
-- 转换后GaussDB-Oracle SQL:
SELECT unisql.uuid();
uuid()
--------------------------------------
664c5710-5ba0-11ef-a608-005056c00001