1.3.3.2.6. 转换为 DM

1.3.3.2.6.1. 其他函数

1.3.3.2.6.1.1. CAST

语法
CAST (expr AS type)
描述
expr 转换为指定的数据类型。

参数

参数

说明

expr

要转换类型的值。

type

转换的目标类型。

注意

1 CAST函数无符号/有符号修饰符处理规则

  • 1.1 不包含SIGNED/UNSIGNED修饰符: 在MySQL中,若CAST函数入参 不包含 SIGNED或UNSIGNED关键字,转换到DM时仍使用CAST函数,但 无法保证源库与目标库数据一致性。 具体转换规则需参考 DM的CAST类型转换相容矩阵

  • 1.2 包含SIGNED/UNSIGNED修饰符: 当CAST函数入参包含SIGNED或UNSIGNED时,采用以下转换逻辑:

    -- 源库MySQL示例
    SELECT CAST('123' AS SIGNED INTEGER);
    
    -- 目标库DM转换结果
    SELECT NVL(TO_NUMBER(REGEXP_SUBSTR('123', '^-?\d+')),0);
    

    详细转换规则参考 DM解决方案:达梦中如何实现 MySQL 中的 signed 语法转换

2 数据类型转换边界行为

  • 2.1 CHAR(N)定长字符截断: 目标数据类型为CHAR(N)时,转换结果将被截断为不超过N个字符。例如:

    SELECT CAST(123.4567 AS CHAR(5));
    -- 源库MariaDB结果:'123.4'
    -- 目标库DM结果:'123.5'(四舍五入)
    
  • 2.2 BINARY类型转换限制: 当目标数据类型为BINARY时,统一SQL解析将报错。

    SELECT CAST("abc" AS BINARY);
    --TargetSql: State:LTU00001 Message:解析失败%!(EXTRA string=错误信息[在第 1 行,第 27 列附近 \"BINARY);\" ] 源SQL[SELECT CAST(\"abc\" AS BINARY);] )
    
  • 2.3 在dm不支持目标数据类型带字符集

    SELECT CAST(123 AS CHAR CHARACTER SET utf8)
    -- 在目标库dm执行直接报错,列[CHARACTER]附近出现错误: 语法分析出错
    

3 特殊值转换兼容性

  • 3.1 非法时间字符串转换

    -- 字符串转TIME:非时间格式字符串(如'Hello World'),SELECT CAST('hello world' AS TIME)
    -- 源库MariaDB:转换为 NULL
    -- 目标库dm报错:非法的时间日期类型数据
    
    --字符串转DATETIME:统一sql不支持转datetime数据类型
    
  • 3.2非法数值转换

    -- 字符串转有符号整数:
    -- 转换前
    SELECT CAST('abc' as  SIGNED) AS `invalid_signed`;
    -- 转换后
    SELECT NVL(TO_NUMBER(REGEXP_SUBSTR('abc', '^-?\d+')), 0) AS invalid_signed
    -- 源库MariaDB和目标库dm:转换为 0
    
    --无效日期时间值:
    SELECT CAST('2023-13-01' as  DATE) AS invalid_date;
    -- mariadb:返回空
    -- dm报错:非法的时间日期类型数据
    
    SELECT CAST('25:61:61' as TIME) AS invalid_time;
    -- mariadb:返回空
    -- dm报错:非法的时间日期类型数据
    
  • 3.3 数值溢出处理

    -- 无符号整数上限:18446744073709551615
    -- 有符号整数范围:-9223372036854775808 ~ 9223372036854775807
    -- 超出边界时
    SELECT CAST(18446744073709551615 AS int)
    -- dm显示数据溢出
    -- maraidb 显示-1
    
  • 3.4 负数转换处理

--负数转signed,比如-123
-- 转换前
SELECT CAST('-123' as  SIGNED) ; --执行结果-123
--转换后
SELECT NVL(TO_NUMBER(REGEXP_SUBSTR('-123', '^-?\d+')), 0); --执行结果-123

--负数转unsigned,比如-123
--转换前
SELECT CAST('-123' as  UNSIGNED) ; --执行结果 18446744073709551493,按照无符号数值处理
--转换后
SELECT NVL(TO_NUMBER(REGEXP_SUBSTR('-123', '^\d+')), 0); --执行结果0

示例

 -- 转换前MySQL SQL:

 SELECT cast(1.5 as SIGNED) as col_signed;
 +------------+
 | col_signed |
 +------------+
 |          2 |
 +------------+

 SELECT cast(1.5 as UNSIGNED) as col_unsigned;
 +--------------+
 | col_unsigned |
 +--------------+
 |            2 |
 +--------------+

 SELECT cast('1.5' as SIGNED) as col_signed;
 +------------+
 | col_signed |
 +------------+
 |          1 |
 +------------+

 SELECT cast('1.5' as UNSIGNED) as col_unsigned;
 +--------------+
 | col_unsigned |
 +--------------+
 |            1 |
 +--------------+

 SELECT cast(1234 as DECIMAL) as  col_decimal;
 +-------------+
 | col_decimal |
 +-------------+
 |        1234 |
 +-------------+

 SELECT cast(STR_TO_DATE('2024-01-31 14:30:00', '%Y-%m-%d %H:%i:%s') as DATE) as col_date;
 +------------+
 | col_date   |
 +------------+
 | 2024-01-31 |
 +------------+

 SELECT cast(STR_TO_DATE('2024-01-31 14:30:00', '%Y-%m-%d %H:%i:%s') as DATETIME) as col_datetime;
 +---------------------+
 | col_datetime        |
 +---------------------+
 | 2024-01-31 14:30:00 |
 +---------------------+



 -- 转换后DM SQL:

SELECT NVL(TO_NUMBER(REGEXP_SUBSTR(1.5, '^-?\d+')), 0) AS col_signed
 col_signed
 ------------
          1

 SELECT NVL(TO_NUMBER(REGEXP_SUBSTR(1.5, '^\d+')), 0) AS col_unsigned
 col_unsigned
 --------------
 1

 SELECT NVL(TO_NUMBER(REGEXP_SUBSTR('1.5', '^-?\d+')), 0) AS col_signed
 col_signed
 ------------
          1

SELECT NVL(TO_NUMBER(REGEXP_SUBSTR('1.5', '^\d+')), 0) AS col_unsigned
 col_unsigned
 --------------
 1

 SELECT CAST(1234 AS decimal(38,0)) AS col_decimal
 col_decimal
 -------------
       1234

 SELECT CAST(STR_TO_DATE('2024-01-31 14:30:00', '%Y-%m-%d %H:%i:%s') AS date) AS col_date
 无法解析的成员访问表达式[STR_TO_DATE]

 SELECT cast(STR_TO_DATE('2024-01-31 14:30:00', '%Y-%m-%d %H:%i:%s') as DATETIME) as col_datetime;
 无法解析的成员访问表达式[STR_TO_DATE]

1.3.3.2.6.1.2. GROUP_CONCAT

语法

GROUP_CONCAT(
    [DISTINCT] expr [, expr ...]
    [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [, col_name ...]]
    [SEPARATOR str_val]
)
描述
在Mariadb中GROUP_CONCAT函数用于将分组内的多行数据连接成一个字符串的函数。它在数据处理中常用于将同一分组的多个值合并为一个单一的值,便于展示或进一步处理。

参数

参数

说明

DISTINCT

(可选)去除重复值,只保留不同的值

expr

(必需)要连接的列或表达式。 以指定多个表达式,用逗号分隔

ORDER BY

(可选)指定连接结果的排序方式。可以按照无符号整数,列名,表达式排序,可以指定升序(ASC)或降序(DESC),默认为ASC

SEPARATOR

(可选)指定连接值之间的分隔符。默认分隔符是逗号(,)可以是任意字符串值

备注

  • 经过统一sql转换到dm的listagg函数,语法:

    LISTAGG (expression [, separator])
    WITHIN GROUP (ORDER BY order_expression [ASC | DESC] [, order_expression [ASC | DESC]...])
    
  • listagg函数参数说明:

    • expression:要聚合的表达式,可以是列名、表达式等。例如,要聚合 product_name 列,就可以写 product_name 作为这个参数。

    • separator:用于指定聚合结果中各个值之间的分隔符。如果不指定,默认为一个空格。例如,要使用逗号和空格作为分隔符,可以写 ', '

    • WITHIN GROUP:用于指定聚合值的排序顺序。order_expression 是用于排序的表达式,通常是列名。可以指定多个排序表达式,并且可以指定排序方向(ASC 为升序,DESC 为降序)。例如,WITHIN GROUP (ORDER BY product_price DESC) 表示按 product_price 列降序排列后进行聚合。

  • listagg函数使用限制:

    • dm中order by 不支持 大文本字段和二进制类型字段,具体范围如下:

      • dm中大文本数据类型:longtext,long,mediumtext,text,tinytext,clob

      • dm中二进制类型:blob,longblob,mediumblob,tinyblob,varbinary

  • 函数行为差异:

    • GROUP_CONCAT:默认无序拼接(结果顺序随机),需显式添加``ORDER BY``才保证顺序,示例:GROUP_CONCAT(name) → “B,A,C”

    • LISTAGG:通过``WITHIN GROUP``指定排序,示例:LISTAGG(name,',') WITHIN GROUP(ORDER BY id) → “A,B,C”

  • 限制说明:

    • 不支持 MariaDB GROUP_CONCAT 函数参数中的 LIMIT,具体语法如下:

      GROUP_CONCAT(
        [DISTINCT] expr [,expr]
        [ORDER BY {unsigned_integer | col_name | expr}[ASC | DESC] [,col_name ...]]
        [SEPARATOR str_val]
        [LIMIT {[offset,] row_count | row_count OFFSET offset}]
      )
      
    • 不支持 GROUP_CONCAT 函数参数中使用分隔符 '\n'

    • mariadb,受系统变量 group_concat_max_len 限制(默认 1024 字节),超过group_concat_max_len ,结果会被截断

    • 拼接顺序不一致。GROUP_CONCAT:默认无序,需显式指定 ORDER BY 才能保证顺序。

    • 表达式计算精度/标度不一致。源库sql举例:SELECT dept_id, GROUP_CONCAT(salary/3) AS divided_salaries FROM employees GROUP BY dept_id;

    • 不支持嵌套聚合函数。源库sql举例:SELECT GROUP_CONCAT(MAX(emp_name)) FROM employees GROUP BY dept_id;

示例

-- 建表和数据准备
    CREATE TABLE student_courses (
      student_id INT,
      student_name VARCHAR(50),
      course_name VARCHAR(50),
      credit INT,
      PRIMARY KEY (student_id, course_name)  -- 联合主键,避免重复选课(后续会插入重复数据测试DISTINCT)
    );

    INSERT INTO student_courses (student_id, student_name, course_name, credit) VALUES
    (1, '张三', '数学', 4),
    (1, '张三', '英语', 3),
    (1, '张三', '物理', 5),
    (1, '张三', '体育', 2),
    (2, '李四', '数学', 4),
    (2, '李四', '英语', 3),
    (2, '李四', '化学', 4),
    (3, '王五', '英语', 3),
    (3, '王五', '生物', 3),
    (3, '王五', '历史', 2),
    (3, '王五', '地理', 2);

    -- 按学生分组,查询每个学生选修的所有课程(包含重复值)
    SELECT
      student_id,
      student_name,
      GROUP_CONCAT(course_name) AS all_courses  -- 默认分隔符为逗号,不排序
    FROM student_courses
    GROUP BY student_id, student_name;

    student_id|student_name|all_courses|
    ----------+------------+-----------+
    1         |张三        |体育,数学,物理,英语|
    2         |李四        |英语,数学,化学   |
    3         |王五        |历史,地理,生物,英语|

    -- 按学生分组,连接课程名称(去重)
    SELECT
      student_id,
      student_name,
      GROUP_CONCAT(DISTINCT course_name) AS unique_courses  -- 去除重复的课程
    FROM student_courses
    GROUP BY student_id, student_name;

    student_id|student_name|unique_courses|
    ----------+------------+--------------+
    1         |张三        |体育,数学,物理,英语   |
    2         |李四        |化学,数学,英语      |
    3         |王五        |历史,地理,生物,英语   |

    -- 按学生分组,课程按学分降序排列(学分高的在前)
    SELECT
      student_id,
      student_name,
      GROUP_CONCAT(DISTINCT course_name ORDER BY credit desc) AS courses_sorted_by_name
    FROM student_courses
    GROUP BY student_id, student_name;

    student_id|student_name|courses_sorted_by_name|
    ----------+------------+----------------------+
             1|张三        |物理,数学,英语,体育           |
             2|李四        |化学,数学,英语              |
             3|王五        |英语,生物,地理,历史           |


-- 用" | "作为分隔符
    SELECT
      student_id,
      student_name,
      GROUP_CONCAT(course_name ORDER BY course_name SEPARATOR ' | ') AS courses_with_pipe
    FROM student_courses
    GROUP BY student_id, student_name;

    student_id|student_name|courses_with_pipe|
    ----------+------------+-----------------+
             1|张三        |体育 | 数学 | 物理 | 英语|
             2|李四        |化学 | 数学 | 英语     |
             3|王五        |历史 | 地理 | 生物 | 英语|


    -- 按课程名称排序后,只连接前2门课程
    SELECT
      student_id,
      student_name,
      GROUP_CONCAT(DISTINCT course_name ORDER BY course_name LIMIT 2) AS first_2_courses
    FROM student_courses
    GROUP BY student_id, student_name;

    student_id|student_name|first_2_courses|
    ----------+------------+---------------+
             1|张三        |体育,数学          |
             2|李四        |化学,数学          |
             3|王五        |历史,地理          |

--转换后

    -- 按学生分组,查询每个学生选修的所有课程(包含重复值)
    SELECT
            student_id,
            student_name,
            listagg(course_name,',') AS all_courses
    FROM
            student_courses
    GROUP BY
            student_id,
            student_name

    STUDENT_ID|STUDENT_NAME|ALL_COURSES|
    ----------+------------+-----------+
             1|张三        |物理,数学,英语,体育|
             2|李四        |化学,数学,英语   |
             3|王五        |生物,地理,英语,历史|

    -- 按学生分组,连接课程名称(去重)
    SELECT
            student_id,
            student_name,
            listagg(DISTINCT course_name,',') AS unique_courses
    FROM
            student_courses
    GROUP BY
            student_id,
            student_name

    STUDENT_ID|STUDENT_NAME|UNIQUE_COURSES|
    ----------+------------+--------------+
             1|张三        |物理,数学,英语,体育   |
             2|李四        |化学,数学,英语      |
             3|王五        |生物,地理,英语,历史   |

    -- 按学生分组,课程按学分降序排列(学分高的在前)
    SELECT
            student_id,
            student_name,
            listagg(DISTINCT course_name,',') WITHIN GROUP (ORDER BY credit desc) AS courses_sorted_by_name
    FROM
            student_courses
    GROUP BY
            student_id,
            student_name

    STUDENT_ID|STUDENT_NAME|COURSES_SORTED_BY_NAME|
    ----------+------------+----------------------+
             1|张三        |物理,数学,英语,体育           |
             2|李四        |数学,化学,英语              |
             3|王五        |生物,英语,历史,地理           |

    -- 用" | "作为分隔符
    SELECT
            student_id,
            student_name,
            listagg(course_name,' | ') WITHIN GROUP (ORDER BY course_name) AS courses_with_pipe
    FROM
            student_courses
    GROUP BY
            student_id,
    student_name
    STUDENT_ID|STUDENT_NAME|COURSES_WITH_PIPE|
    ----------+------------+-----------------+
             1|张三        |数学 | 体育 | 物理 | 英语|
             2|李四        |化学 | 数学 | 英语     |
             3|王五        |地理 | 历史 | 生物 | 英语|

    -- 按课程名称排序后,只连接前2门课程
    解析失败%!(EXTRA string=错误信息[在第 4 行,第 65 列 附近 "LIMIT 2) AS first_2_courses

1.3.3.2.6.1.3. UUID

语法
UUID ()
描述
用于生成一个唯一的标识符(UUID),保证在空间和时间上的唯一性

示例

-- 转换前MySQL SQL :
select uuid();
+--------------------------------------+
| uuid()                               |
+--------------------------------------+
| 664c5710-5ba0-11ef-a608-005056c00001 |
+--------------------------------------+

-- 转换后:
SELECT newid() from dual;
NEWID()
------------------------------------
3B62EC6A-E5BB-11B2-B5AB-186CD7E66B21

1.3.3.2.6.1.4. STR_TO_DATE

语法
STR_TO_DATE(str, format)
描述
接受一个字符串 str 和一个格式字符串 format,返回一个日期时间类型的值

参数解释

参数

说明

str

日期时间的字符串

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/maraidb 参数字符串 str 未指定的时间或日期部分将默认0,因此部分信息缺失时候会返回0的时间或日期,目标库DM返回空或者当前的日期时间、当前月份的1号等;

  • 字符串 str 如果是英文,目标库DM需要设置 NLS_DATE_LANGUAGE为ENGLISH;

  • 源库mysql/maraidb 参数字符串 str 若无法根据数据库规则解析,结果返回NULL并产生一个警告,目标库DM直接返回报错;

  • 源库mysql/maraidb 参数字符串 str 多于指定的时间或日期部分,结果返回指定的时间或日期,DM直接返回报错。

示例

-- 转换前MySQL SQL:
SELECT STR_TO_DATE('2024-01-05 12:09:40', '%Y-%m-%d %H:%i:%s')
STR_TO_DATE('2024-01-05 12:09:40', '%Y-%m-%d %H:%i:%s')|
-------------------------------------------------------+
                                2024-01-05 12:09:40.000|
-- 转换后 DM SQL:
SELECT to_timestamp('2024-01-05 12:09:40', 'YYYY-MM-DD HH24:MI:SS');
TO_TIMESTAMP('2024-01-0512:09:40','YYYY-MM-DDHH24:MI:SS')|
---------------------------------------------------------+
                                  2024-01-05 12:09:40.000|


-- 转换前MySQL SQL:
SELECT STR_TO_DATE('2024-02-12', '%Y-%m-%d')
STR_TO_DATE('2024-02-12', '%Y-%m-%d')|
-------------------------------------+
                          2024-02-12|
-- 转换后 DM SQL:
SELECT CAST(to_timestamp('2024-02-12', 'YYYY-MM-DD') AS date);
CAST(TO_TIMESTAMP('2024-02-12','YYYY-MM-DD')ASDATE)|
---------------------------------------------------+
                                        2024-02-12|


-- 转换前MySQL SQL:
SELECT STR_TO_DATE('08:09:40', '%H:%i:%s')
STR_TO_DATE('08:09:40', '%H:%i:%s')|
-----------------------------------+
                           08:09:40|
-- 转换后 DM SQL:
SELECT CAST(to_timestamp('08:09:40', 'HH24:MI:SS') AS time)
CAST(TO_TIMESTAMP('08:09:40','HH24:MI:SS')ASTIME)|
-------------------------------------------------+
                                        08:09:40|

-- 转换前MySQL SQL,反例:
SELECT STR_TO_DATE('2024-02-12 12:12:12', '%Y-%m-%d')
STR_TO_DATE('2024-02-12 12:12:12', '%Y-%m-%d')|
----------------------------------------------+
                                    2024-02-12|
-- 转换后 DM SQL,执行报错:
SELECT CAST(to_timestamp('2024-02-12 12:12:12', 'YYYY-MM-DD') AS date);



-- 转换前MySQL SQL,反例:
SELECT STR_TO_DATE('', '%Y-%m-%d')
STR_TO_DATE('', '%Y-%m-%d')|
---------------------------+
                0000-00-00|
-- 转换后 DM SQL:
SELECT CAST(to_timestamp('', 'YYYY-MM-DD') AS date);
CAST(TO_TIMESTAMP('','YYYY-MM-DD')ASDATE)|
-----------------------------------------+
                                         |

1.3.3.2.6.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位

警告

  • date_format函数在 DM 中转化为unisql.date_format函数,日期时间格式的转化支持如上表。

  • 在目标库为 DM,如果遇到非上述表格中的日期格式,日期时间格式的转换遵循以下规则:首先按空格将格式字符串拆分为多个片段,并依次进行转换。若某一片段完全由不支持转换的格式组成,则整个表达式将被转换为 CONCAT 函数形式。该函数用于拼接前面可成功转换的部分与该不可转换片段及其后续内容,从而形成最终的表达式。

  • 时间格式’%M’、’%p’、’%W’,DM 可以通过 NLS_DATE_LANGUAGE 设定日期返回的语言,转换后的sql执行结果与 MARIADB 存在差异。

  • 时间格式与时间格式之间不允许出现空格,转换后的sql执行结果与 MARIADB 存在差异。

  • 不支持 MARIADB 时间格式’%Q’、’%a’、’%D’、’%j’、’%U’、’%u’、’%V’、’%v’、’%w’、’%X’、’%x’,转换后的sql执行结果与 MARIADB 存在差异。

  • 不支持通配符的写法’%%’,转换后的sql执行结果与 MARIADB 存在差异。

  • LAST_DAY函数,转换后的sql执行结果与 MARIADB 存在差异。

  • DATE_FORMAT第一个参数为空时,第二个参数带常量,此时可能输出常量,也可能输出 NULL,,由 DM 数据库版本控制,转换后的sql执行结果与 MARIADB 存在差异。

  • 不支持格式中包换时间格式和其他字符组合的情况,如%Y-%m-%d %H:aa:%s,其中%H:aa:%s不符合DM的时间格式要求,转换成功执行报错。

  • 时间格式与常量字符之间需要有空格,如’%Y-%m-%dabc123’,转换成功执行报错。

  • 不支持函数CONVERT_TZ、ADDTIME、SUBTIME、MAKETIME、TIMEDIFF、DATEDIFF、TIMESTAMPADD、TIMESTAMPDIFF、UTC_DATE、UTC_TIME、MICROSECOND、PERIOD_ADD、PERIOD_DIFF、STR_TO_DATE、WEEK、DAYNAME、MONTHNAME,转换成功执行报错。

  • 不支持时间格式与中文混合使用,如’%Y年%m月%d日’,转换成功执行报错。

示例

-- 转换前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                                     |
+---------------------------------------------------------+

-- 转换后 DM 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


-- 转换前MySQL SQL:
select date_format('2020-01-01 08:13:13', '%Y/%m/%d 00:00:00');
date_format('2020-01-01 08:13:13', '%Y/%m/%d 00:00:00')|
-------------------------------------------------------+
2020/01/01 00:00:00                                    |

-- 转换后 DM SQL:
SELECT concat(unisql.date_format('2020-01-01 08:13:13', 'YYYY/MM/DD'), ' 00:00:00')
concat             |
-------------------+
2020/01/01 00:00:00|

-- 转换前MySQL SQL,反例:
select date_format('2020-01-01 08:13:13', '%Y/%m/%d unisql %s');
date_format('2020-01-01 08:13:13', '%Y/%m/%d unisql %s')|
--------------------------------------------------------+
2020/01/01 unisql 13                                    |

-- 转换后 DM SQL:
SELECT concat(unisql.date_format('2020-01-01 08:13:13', 'YYYY/MM/DD'), ' unisql %s')
concat              |
--------------------+
2020/01/01 unisql %s|

1.3.3.2.6.1.6. DATE_ADD

语法
DATE_ADD(date,INTERVAL expr unit)
描述
用于将指定的时间间隔添加到日期或时间值上,目标库返回的日期时间类型为TIMESTAMP。

参数解释

参数

说明

date

日期时间,该参数可以为date、datetime、timestamp数据类型、字符串范围为年月日、年月日 时分秒;日期分隔符(-、/、.),时间分隔符(:、.)不可混用每次只能用一种,不支持中文和时区;

expr

时间值,正整数或负整数,正数表示向未来增加时间间隔,负数表示向过去减少时间间隔

unit

时间间隔,该参数为interval类型,支持清单:年(year)/月(month)/日(day)/时(hour)/分(minute)/秒(second)

警告

  • 经统一sql转换后返回的类型是TIMESTAMP,返回的内容值精度到毫秒;

  • expr只支持整数,不支持小数和表达式等;

  • expr值超过阈值mysql返回的是null,达梦则会报错;

  • date的入参format的格式为:年月日时分秒的顺序格式,不支持中文和时区,不支持int和number类型;

示例

-- 转换前MySQL SQL:
SELECT DATE_ADD('2024-02-29', INTERVAL 1 year);
DATE_ADD('2024-02-29', INTERVAL 1 year)|
---------------------------------------+
2025-02-28                             |

-- 转换后DM SQL:
SELECT dateadd(YEAR, 1, '2024-02-29')
DATEADD(YEAR,1,'2024-02-29')|
----------------------------+
    2025-02-28 00:00:00.000|

1.3.3.2.6.1.7. DATE_SUB

语法
DATE_SUB(date,INTERVAL expr unit)
描述
用于从指定的日期或时间值中减去一个时间间隔,目标库返回的日期时间类型为TIMESTAMP。

参数解释

参数

说明

date

日期时间,该参数可以为date、datetime、timestamp数据类型、字符串范围为年月日、年月日 时分秒;日期分隔符(-、/、.),时间分隔符(:、.)不可混用每次只能用一种,不支持中文和时区;

expr

时间值,正整数或负整数,正数表示向过去减少时间间隔,负数表示向未来增加时间间隔

unit

时间间隔,该参数为interval类型,支持清单:年(year)/月(month)/日(day)/时(hour)/分(minute)/秒(second)

警告

  • 经统一sql转换后返回的类型是TIMESTAMP,返回的内容值精度到毫秒;

  • expr只支持整数,不支持小数和表达式等;

  • expr值超过阈值mysql返回的是null,达梦则会报错;

  • date的入参format的格式为:年月日时分秒的顺序格式,不支持中文和时区,不支持int和number类型;

示例

-- 转换前MySQL SQL:
SELECT DATE_SUB('2025-02-28', INTERVAL 1 year);
DATE_SUB('2025-02-28', INTERVAL 1 year)|
---------------------------------------+
2024-02-28                             |

-- 转换后DM SQL:
SELECT dateadd(YEAR, -1, '2025-02-28')
DATEADD(YEAR,-1,'2025-02-28')|
-----------------------------+
      2024-02-28 00:00:00.000|

1.3.3.2.6.1.8. CONVERT

语法
CONVERT (expr using transcoding_name)
描述
将expr转换为指定的编码类型。

参数解释

参数

说明

expr

要转换的表达式

transcoding_name

指定的编码格式,目前支持utf8,utf8mb4,gbk

警告

  • 需要设置DM数据库的ENABLE_CS_CVT参数为1;

  • 将表达式 expr 转换为指定编码类型时,目前支持 utf8, utf8mb4, gbk;

示例

-- 转换前MySQL SQL:
SELECT  CONVERT('你好, world!' USING utf8);
SELECT  CONVERT('你好, world!' USING utf8mb4);
SELECT  CONVERT('你好, world!' USING gbk);


-- 转换后DM SQL:
SELECT convert('你好, world!', 'utf8');
SELECT convert('你好, world!', 'AL32UTF8');
SELECT convert('你好, world!', 'ZHS16GBK');

1.3.3.2.6.1.9. UNIX_TIMESTAMP

语法
UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
描述
返回自 1970-01-01 00:00:00 UTC 起到某一时间点的秒数,如果没有参数返回到当前时间点的秒数

参数解释

参数

说明

date

日期时间

警告

  • 参数为空串,源库mariadb的值返回null,mysql的值返回0,目标库达梦,返回值0;

  • 参数的值小于1970-01-01 00:00:00 UTC,源库mariadb的值返回null,mysql的值返回0,目标库达梦,返回值0;

  • 参数的值大于2038-01-19,源库mariadb的值返回null,mysql的值返回0,目标库达梦,返回值0;

  • 参数为timestamp、datetime类型且秒有精度,源库mariadb的值返回值会带小数部分,目标库达梦,返回值不带小数部分;

  • 参数为日期时间的字符串类型且秒有精度,源库mariadb的值返回值会带小数部分,最长四舍五入截止到6位,目标库达梦,返回值带小数部分,最长截止到6位。

示例

-- 转换前MySQL SQL:
SELECT UNIX_TIMESTAMP('2025-04-21 17:45:00')
UNIX_TIMESTAMP('2025-04-21 17:45:00')|
-------------------------------------+
                          1745228700|
-- 转换后 DM的SQL:
SELECT UNIX_TIMESTAMP('2025-04-21 17:45:00')
UNIX_TIMESTAMP('2025-04-2117:45:00')|
------------------------------------+
                          1745228700|

-- 转换前MySQL SQL:
SELECT UNIX_TIMESTAMP()
UNIX_TIMESTAMP()|
----------------+
      1755670763|
-- 转换后 DM的SQL:
SELECT UNIX_TIMESTAMP(sysdate())
UNIX_TIMESTAMP(SYSDATE())|
-------------------------+
              1755670763|

1.3.3.2.6.1.10. TIMESTAMP

语法
TIMESTAMP(dateExpr)
TIMESTAMP(dateExpr,timeExpr)
描述
传一个参数 dateExpr:返回 dateExpr 转换成 DATETIME 格式的值
传两个参数 dateExpr 和 timeExpr:返回一个 DATETIME,它等于dateExpr 的日期时间部分和timeExpr的时间部分相加。

参数解释

参数

说明

dateExpr

日期时间表达式

timeExpr

时间表达式

警告

  • 源库mysql、mariadb ,目标库dm 的字符串、数字隐式转化成日期时间类型有差异,会造成结果值有差异;

  • 第二个参数timeExpr必须是time类型或者标准的时间格式字符串(类型HH24:MI:SS[.FF6]);

  • 对于非法传参,源库mariadb的值返回null,目标库达梦返回错误;

  • 只传一个参数,参数类型是time类型,源库Mariadb返回值结果为当前日期和参数time相加,目标库DM返回值结果为1900-01-01和参数time相加;

  • 结果返回值会若带小数部分,源库mariadb的值最长四舍五入截止到6位,目标库达梦最长直接截止到6位;

  • 对极值的支持不同,源库mariadb的支持极值日期时间0000-00-00 00:00:00,目标库达梦支持的极值为0001-01-01 00:00:00。

示例

-- 转换前MySQL SQL:
SELECT timestamp('2025-04-21 17:45:00')
timestamp('2025-04-21 17:45:00')|
--------------------------------+
        2025-04-21 17:45:00.000|
-- 转换后 DM的SQL:
SELECT CAST('2025-04-21 17:45:00' AS datetime)
CAST('2025-04-2117:45:00'ASDATETIME)|
------------------------------------+
            2025-04-21 17:45:00.000|

-- 转换前MySQL SQL:
SELECT timestamp('2025-04-21 17:45:00','21:23:45')
timestamp('2025-04-21 17:45:00','21:23:45')|
-------------------------------------------+
                    2025-04-22 15:08:45.000|
-- 转换后 DM的SQL:
SELECT unisql.timestamp('2025-04-21 17:45:00', '21:23:45')
UNISQL.TIMESTAMP('2025-04-2117:45:00','21:23:45')|
-------------------------------------------------+
                          2025-04-22 15:08:45.000|

1.3.3.2.6.1.11. TIME_FORMAT

语法
TIME_FORMAT(time,format)
描述
用于根据指定格式格式化时间值。它返回一个字符串,表示根据格式字符串格式化的时间。

参数解释

参数

说明

time

指定时间

format

时间显示格式,支持清单详见 date_format 一节

警告

  • time中小时部分如果大于23(MARIADB 支持,正确用法),转换会成功,执行结果不一致。

  • time 如果为字符串,其中的分钟,秒部分超过60(MARIADB 不支持,错误用法),转换成功,执行结果不一致。MARIADB 为NULL。

  • time 如果为字符串,只能为 'hour:minute:second' 格式,不然在DM执行报错。

  • format 为NULL, 转换失败。

  • format 为空串,转换成功,执行报错。MARIADB 执行结果为NULL。

  • format 部分如果包含日期格式 ,转换会成功,执行不一致(MARIADB 为null, DM 会起效,因为to_char支持日期格式)

  • 时间格式’%p’、’%r’,DM 可以通过 NLS_DATE_LANGUAGE 设定日期返回的语言,转换后的sql执行结果与 MARIADB 存在差异。

  • 不支持通配符的写法’%%’,转换后的sql执行结果与 MARIADB 存在差异。

  • 不支持格式中的常量字符,如%H:aa:%s,%H:aa:%s不符合DM的时间格式要求,转换成功执行报错。

  • format 只能为常量字符串,不然转换报错

示例

-- 转换前MySQL SQL:
SELECT TIME_FORMAT(SYSDATE(), '%H-%i-%s') FROM dual;
+------------------------------------+
| TIME_FORMAT(SYSDATE(), '%H-%i-%s') |
+------------------------------------+
| 16-46-00                           |
+------------------------------------+
1 row in set (0.00 sec)


-- 转换后 SQL:
SELECT to_char(sysdate, 'HH24-MI-SS') FROM dual
TO_CHAR(SYSDATE,'HH24-MI-SS')
-----------------------------
16-45-02

1.3.3.2.6.1.12. COMPRESS

语法
compress (plaintext)
描述
压缩字符串并返回二进制数据。

参数解释

参数

说明

plaintext

需要压缩的明文,该参数为字符串类型

警告

示例

-- 转换前MySQL SQL:
select compress('123abc你好');
+----------------------------------------------------+
| compress('123abc你好')                             |
+----------------------------------------------------+
| 0x0C000000789C3334324E4C4A7EB277C1D3A57B011FE90645 |
+----------------------------------------------------+

-- 转换后dm SQL:
SELECT UTL_RAW.CAST_TO_RAW('123abc你好') from dual;
+-------------------------------------+
| UTL_RAW.CAST_TO_RAW('123ABC你好')   |
+-------------------------------------+
| 123abcÄãºÃ                          |
+-------------------------------------+

1.3.3.2.6.1.13. UNCOMPRESS

语法
uncompress (ciphertext)
描述
解压由compress()函数压缩的二进制数据, 返回blob类型。

警告

  • 未实现解压行为,仅将参数转为blob类型。

  • 只支持RAW类型参数,对于DM的 VARBINARY 数据类型。

  • 参数为空串时返回NULL,mysql返回空串

参数解释

参数

说明

ciphertext

需要解压缩的密文,该参数为二进制类型RAW。

示例

-- 转换前MySQL SQL:
select uncompress(compress('123abc你好'));
+------------------------------------+
| uncompress(compress('123abc你好')) |
+------------------------------------+
| 0x313233616263E4BDA0E5A5BD         |
+------------------------------------+

-- 转换后dm SQL:
SELECT to_blob(UTL_RAW.CAST_TO_RAW('123abc你好')) from dual;
+------------------------------------------------------------------------------------------+
| TO_BLOB(UTL_RAW.CAST_TO_RAW('123ABC你好'))                                               |
+------------------------------------------------------------------------------------------+
| 123abcÄãºÃ                                                                               |
+------------------------------------------------------------------------------------------+

1.3.3.2.6.1.14. WEEKOFYEAR

语法
WEEKOFYEAR(date)
描述
返回日期为所在年中的第几周。

参数解释

参数

说明

date

日期时间,该参数可以为date、datetime、timestamp数据类型、字符串范围为年月日、年月日 时分秒;日期分隔符(-、/、.),时间分隔符(:、.)不可混用每次只能用一种,不支持中文和时区;

警告

  • date值超过阈值或非法mysql返回的是null,达梦则会报错;

  • date的入参format的格式为:年月日时分秒的顺序格式,不支持中文和时区,不支持int和number类型;

示例

-- 转换前MySQL SQL:
SELECT WEEKOFYEAR('2025-02-28');
WEEKOFYEAR('2025-02-28')|
------------------------+
                      9|

-- 转换后DM SQL:
SELECT week('2025-02-28', 3)
WEEK('2025-02-28',3)|
--------------------+
                  9|