MySQL和达梦数据库SQL语法差异对比示例总结

 更新时间:2026年07月09日 10:43:57   作者:牛马爱开会  
目前国内的很多领域大部分通用会使用到达梦数据库,这篇文章主要介绍了MySQL和达梦数据库SQL语法差异对比的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在国内项目里,常见场景是:原来用 MySQL,后来要上国产数据库(如达梦 DM8/DM7);或者新项目要同时兼容两种数据库。

本文从“实战迁移”角度,系统梳理 MySQL 和达梦数据库在 SQL 语法上的差异,并用对照示例帮助你快速上手。

一、整体定位与兼容思路

  • MySQL

    • 典型的开源关系型数据库,SQL语法偏向自成一派,也兼容部分标准SQL。
    • 习惯用 LIMIT 分页、AUTO_INCREMENT 自增主键、大量内置函数(如 IFNULLNOW() 等)。
  • 达梦数据库(DM)

    • 国产数据库,整体高度兼容 Oracle 语法,同时提供一定的 MySQL 兼容特性(需要配置兼容模式)。
    • 更标准化,事务与约束语义更严谨,支持 SEQUENCEROWNUMDUAL 等 Oracle 风格语法。

实战建议:

  • 如果是从 MySQL 迁移到达梦,优先按“Oracle 风格”来写 SQL,更稳定、功能更全。
  • 纯应用开发中,尽量避免写死数据库特定语法(比如 LIMIT),用统一的 DAO/ORM 分页封装。

二、数据类型差异

2.1 数值类型对比

场景MySQL达梦(DM)备注
整型,主键INT, BIGINTINT, BIGINT, NUMBER(p)DM 里用 NUMBER 也很常见
浮点FLOAT, DOUBLEFLOAT, DOUBLE, NUMBER(p,s)建议改用 NUMBER(p,s) 控制精度
定点小数(金额)DECIMAL(p,s)DECIMAL(p,s)NUMBER(p,s)语义类似

示例:

MySQL 建表(金额字段):

CREATE TABLE order_info_mysql (
    id        BIGINT PRIMARY KEY AUTO_INCREMENT,
    amount    DECIMAL(18, 2),
    discount  FLOAT
);

达梦推荐写法:

CREATE TABLE order_info_dm (
    id        BIGINT PRIMARY KEY,
    amount    NUMBER(18, 2),
    discount  NUMBER(10, 4)
);

迁移时重点关注:DECIMAL/NUMBER 精度,避免金额、统计类字段精度丢失。

2.2 字符串类型对比

场景MySQL达梦(DM)备注
可变长度字符串VARCHAR(n)VARCHAR2(n)VARCHAR(n)达梦中更偏向 Oracle 风格 VARCHAR2
固定长度字符串CHAR(n)CHAR(n)基本一致
大文本TEXT, MEDIUMTEXT, LONGTEXTCLOB迁移时一般 TEXT → CLOB
二进制BLOB 系列BLOB名称类似

示例:

MySQL:

CREATE TABLE user_mysql (
    id       BIGINT PRIMARY KEY AUTO_INCREMENT,
    name     VARCHAR(50),
    bio      TEXT
);

达梦:

CREATE TABLE user_dm (
    id       BIGINT PRIMARY KEY,
    name     VARCHAR2(50),
    bio      CLOB
);

2.3 日期时间类型对比

场景MySQL达梦(DM)备注
日期DATEDATE都只保存日期
日期+时间DATETIME, TIMESTAMPTIMESTAMPDM 的 DATE 更接近 Oracle 的 DATE(含时间)视版本配置而定
当前时间函数NOW(), CURRENT_TIMESTAMPSYSDATE, SYSTIMESTAMP, CURRENT_TIMESTAMP迁移时重点是函数名差异

常见写法对比:

MySQL:

SELECT NOW(), CURDATE();

达梦:

SELECT SYSDATE, CURRENT_DATE FROM DUAL;

三、自增主键与序列

这是从 MySQL 迁移到达梦时最常踩坑的地方之一。

3.1 MySQL:AUTO_INCREMENT

CREATE TABLE user_mysql (
    id   BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50)
);

插入时可以不写 id

INSERT INTO user_mysql (name) VALUES ('Tom');

3.2 达梦:IDENTITY 或 SEQUENCE

达梦有两种常用方案:

  1. IDENTITY(类似自增):
CREATE TABLE user_dm_identity (
    id   BIGINT IDENTITY(1,1) PRIMARY KEY,
    name VARCHAR2(50)
);

插入:

INSERT INTO user_dm_identity (name) VALUES ('Tom');
  1. SEQUENCE + 触发器/应用赋值(Oracle 风格)
CREATE SEQUENCE seq_user_dm
    START WITH 1
    INCREMENT BY 1;

CREATE TABLE user_dm (
    id   BIGINT PRIMARY KEY,
    name VARCHAR2(50)
);

应用层插入(典型写法):

INSERT INTO user_dm (id, name)
VALUES (seq_user_dm.NEXTVAL, 'Tom');

实战建议:

  • 新项目尽量使用 IDENTITY 简化开发;
  • 如需跨表统一主键生成,适合用 SEQUENCE,并统一封装在 DAO 层。

四、分页查询写法差异

4.1 MySQL:LIMIT 语法

SELECT * FROM user_mysql
ORDER BY id
LIMIT 10 OFFSET 20;  -- 从第21行开始,取10行

或:

SELECT * FROM user_mysql
ORDER BY id
LIMIT 20, 10;        -- 同样效果

4.2 达梦(Oracle 风格):ROWNUM 或窗口函数

标准 SQL + Oracle 风格两种常用写法。

写法一:ROWNUM 双层子查询

SELECT *
FROM (
    SELECT u.*, ROWNUM AS rn
    FROM user_dm u
    ORDER BY u.id
) t
WHERE t.rn > 20 AND t.rn <= 30;

写法二:窗口函数 ROW_NUMBER()

SELECT *
FROM (
    SELECT u.*, ROW_NUMBER() OVER (ORDER BY u.id) AS rn
    FROM user_dm u
) t
WHERE t.rn > 20 AND t.rn <= 30;

提示:

  • ORM(如 MyBatis、JPA)一般都有“分页方言”配置,把 LIMIT 自动转换为对应数据库语法。
  • 若自己拼 SQL,建议在 DAO/Repository 层封装统一分页接口。

五、字符串与日期函数差异

5.1 常用字符串函数对比

功能MySQL达梦(DM)
字符串长度LENGTH(str)(字节), CHAR_LENGTH(str)(字符)LENGTH(str)(字符)
子串SUBSTRING(str, pos, len)SUBSTR(str, pos, len)
拼接CONCAT(a, b, ...)CONCAT(a, b) 或 字符串拼接符 `
查找位置INSTR(str, substr)INSTR(str, substr)
大小写UPPER(str), LOWER(str)UPPER(str), LOWER(str)

示例对比:

MySQL:

SELECT CONCAT(first_name, ' ', last_name) AS full_name
FROM user_mysql
WHERE INSTR(name, 'Tom') > 0;

达梦:

SELECT first_name || ' ' || last_name AS full_name
FROM user_dm
WHERE INSTR(name, 'Tom') > 0;

迁移时重点替换:CONCAT 多参数 → 使用 || 或多层嵌套 CONCAT

5.2 日期格式化与解析

  • MySQL:

    • DATE_FORMAT(date, '%Y-%m-%d %H:%i:%s')
    • STR_TO_DATE(str, '%Y-%m-%d %H:%i:%s')
  • 达梦(Oracle 风格):

    • TO_CHAR(date, 'YYYY-MM-DD HH24:MI:SS')
    • TO_DATE(str, 'YYYY-MM-DD HH24:MI:SS')

示例对比:

MySQL:

SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s') AS now_str;

达梦:

SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') AS now_str
FROM DUAL;

MySQL 插入字符串日期:

INSERT INTO logs_mysql (create_time)
VALUES (STR_TO_DATE('2024-01-01 10:20:30', '%Y-%m-%d %H:%i:%s'));

达梦:

INSERT INTO logs_dm (create_time)
VALUES (TO_DATE('2024-01-01 10:20:30', 'YYYY-MM-DD HH24:MI:SS'));

六、空值判断与条件函数

6.1 空值判断函数

  • MySQL:IFNULL(expr1, expr2)
  • 达梦:NVL(expr1, expr2)(Oracle 风格)、也支持 COALESCE(...)

示例:

MySQL:

SELECT IFNULL(nickname, '匿名') AS nick
FROM user_mysql;

达梦:

SELECT NVL(nickname, '匿名') AS nick
FROM user_dm;

6.2 条件表达式

  • MySQL:IF(condition, a, b)CASE WHEN
  • 达梦:推荐使用标准 CASE WHEN,同时也支持 Oracle 风格 DECODE

MySQL:

SELECT
    IF(status = 1, '启用', '禁用') AS status_name
FROM user_mysql;

达梦(推荐):

SELECT
    CASE WHEN status = 1 THEN '启用' ELSE '禁用' END AS status_name
FROM user_dm;

达梦(DECODE):

SELECT
    DECODE(status, 1, '启用', '禁用') AS status_name
FROM user_dm;

实战建议:为减少多库差异,统一使用 CASE WHEN,MySQL 和达梦都支持。

七、系统表与元数据查询差异

在运维、代码生成、自动建模时,经常会查询“表结构信息、索引信息”。

7.1 查看所有表

  • MySQL:
SHOW TABLES;
  • 达梦(当前用户下的表):
SELECT TABLE_NAME
FROM USER_TABLES;

查看所有可见表:

SELECT OWNER, TABLE_NAME
FROM ALL_TABLES;

7.2 查看表结构

  • MySQL:
DESC user_mysql;
-- 或
SHOW COLUMNS FROM user_mysql;
  • 达梦:
SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, NULLABLE
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = 'USER_DM';

提示:达梦的元数据视图设计几乎与 Oracle 一致,可以直接套用大量 Oracle 的管理经验。

八、事务与锁:语义类似,但默认行为不同

8.1 基本事务语法

MySQL 与达梦的事务控制语法基本一致:

-- 开启事务(MySQL + InnoDB & 达梦)
START TRANSACTION;

UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;

COMMIT;  -- 或 ROLLBACK;

8.2 差异点提示

  • MySQL 不同引擎(InnoDB/MyISAM)事务和锁语义差别较大,而达梦本身就是完全事务型数据库。
  • 达梦对约束的检查与执行更严格,一些在 MySQL 能“侥幸通过”的操作,在达梦会直接报错。

迁移时常见问题:

  • 插入/更新时违反外键、唯一约束,在 MySQL 被默认忽略或以 Warning 形式出现;到了达梦会直接报错——需要在代码层真正处理异常、保证数据一致性。

九、索引与约束语法差异

9.1 唯一约束与唯一索引

MySQL:

CREATE TABLE user_mysql (
    id     BIGINT PRIMARY KEY AUTO_INCREMENT,
    email  VARCHAR(100) UNIQUE
);

CREATE UNIQUE INDEX idx_user_email
ON user_mysql (email);

达梦:

CREATE TABLE user_dm (
    id     BIGINT PRIMARY KEY,
    email  VARCHAR2(100),
    CONSTRAINT uk_user_email UNIQUE (email)
);

CREATE UNIQUE INDEX idx_user_email
ON user_dm (email);

达梦更推荐显式命名约束CONSTRAINT xxx),便于后期变更和管理。

9.2 外键约束

写法基本一致,但达梦会更严格地执行外键检查。

MySQL:

CREATE TABLE order_mysql (
    id         BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id    BIGINT,
    CONSTRAINT fk_order_user
        FOREIGN KEY (user_id) REFERENCES user_mysql(id)
);

达梦:

CREATE TABLE order_dm (
    id         BIGINT PRIMARY KEY,
    user_id    BIGINT,
    CONSTRAINT fk_order_user
        FOREIGN KEY (user_id) REFERENCES user_dm(id)
);

十、常见 SQL 场景对照示例(汇总版)

这一节给出常用业务场景的“完整对照”,方便直接复制对比。

10.1 按条件分页查询用户列表

MySQL 写法:

SELECT id, name, age
FROM user_mysql
WHERE age >= 18
ORDER BY create_time DESC
LIMIT 20, 10;

达梦写法(ROW_NUMBER 分页):

SELECT *
FROM (
    SELECT
        u.id,
        u.name,
        u.age,
        ROW_NUMBER() OVER (ORDER BY u.create_time DESC) AS rn
    FROM user_dm u
    WHERE u.age >= 18
) t
WHERE t.rn > 20 AND t.rn <= 30;

10.2 统计每天注册用户数(按日期分组)

MySQL:

SELECT
    DATE_FORMAT(create_time, '%Y-%m-%d') AS dt,
    COUNT(*) AS cnt
FROM user_mysql
GROUP BY DATE_FORMAT(create_time, '%Y-%m-%d')
ORDER BY dt;

达梦:

SELECT
    TO_CHAR(create_time, 'YYYY-MM-DD') AS dt,
    COUNT(*) AS cnt
FROM user_dm
GROUP BY TO_CHAR(create_time, 'YYYY-MM-DD')
ORDER BY dt;

10.3 根据状态分类统计(条件表达式)

MySQL:

SELECT
    SUM(IF(status = 1, 1, 0)) AS active_cnt,
    SUM(IF(status = 0, 1, 0)) AS inactive_cnt
FROM user_mysql;

达梦(推荐 CASE WHEN 写法):

SELECT
    SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS active_cnt,
    SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS inactive_cnt
FROM user_dm;

十一、迁移与多库兼容的实战建议

  • 尽量使用“交集语法”

    • 条件表达式统一用 CASE WHEN
    • 分组统计中避免用过于 MySQL 特有的函数;
    • SQL 尽量标准化,业务逻辑放在应用层或存储过程里。
  • 把差异点封装在 DAO / 分页工具 / SQL 构造器中

    • 分页、日期函数、空值函数等统一由“数据访问层”负责差异转换;
    • 应用层尽量只关心业务字段和语义,不直接写方言级语法。
  • 建库建表脚本分库维护

    • MySQL 一份 DDL,达梦一份 DDL,不建议用一份 DDL 试图兼容所有数据库;
    • 可以用代码生成器根据“中立模型(字段名/类型语义)”分别生成多库 DDL。
  • 测试覆盖约束、事务边界

    • 特别是外键、唯一约束、非空约束;
    • 在达梦下把错误全部跑一遍,修正掉原来 MySQL 下被忽视的数据质量问题。

十二、总结

  • MySQL 与达梦在 SQL 层面的核心差异主要集中在:

    • 数据类型命名(VARCHAR2 / NUMBER / CLOB)
    • 自增主键实现方式(AUTO_INCREMENT vs IDENTITY/SEQUENCE)
    • 分页写法(LIMIT vs ROWNUM / 窗口函数)
    • 函数体系(IFNULL / DATE_FORMAT / STR_TO_DATE vs NVL / TO_CHAR / TO_DATE)
    • 系统表与元数据视图(SHOW TABLES vs USER_TABLES 等)
  • 掌握这些关键差异后,你就可以较为顺畅地:

    • 将 MySQL 项目迁移到达梦;
    • 或在一个项目中同时支持 MySQL + 达梦两种数据库。

到此这篇关于MySQL和达梦数据库SQL语法差异对比总结的文章就介绍到这了,更多相关MySQL和达梦SQL语法差异内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL IS NULL空值查询的实现

    MySQL IS NULL空值查询的实现

    MySQL 提供了 IS NULL 关键字,用来判断字段的值是否为空值,本文主要介绍了MySQL IS NULL空值查询的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • 窥探mysql存储过程细节

    窥探mysql存储过程细节

    这篇文章主要为大家详细介绍了mysql存储过程细节,对mysql存储过程感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 在DataGrip中操作MySQL完整流程步骤(从登录到数据查询)

    在DataGrip中操作MySQL完整流程步骤(从登录到数据查询)

    DataGrip是JetBrains公司出品的一款现代化数据库管理工具,支持多种数据库系统,包括MySQL,这篇文章主要介绍了在DataGrip中操作MySQL完整流程步骤的相关资料,需要的朋友可以参考下
    2025-11-11
  • Mysql使用insert插入多条记录 批量新增数据

    Mysql使用insert插入多条记录 批量新增数据

    这篇文章主要介绍了Mysql使用insert插入多条记录批量新增数据,需要的朋友可以参考下
    2017-08-08
  • Mysql数据库之索引优化

    Mysql数据库之索引优化

    MySQL凭借着出色的性能、低廉的成本、丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库。本文给大家介绍mysql数据库之索引优化,感兴趣的朋友一起学习吧
    2016-03-03
  • mysql ON DUPLICATE KEY UPDATE语句示例

    mysql ON DUPLICATE KEY UPDATE语句示例

    本文介绍一下关于mysql中INSERT INTO… ON DUPLICATE KEY UPDATE用法
    2013-11-11
  • Mysql之如何根据.frm和.idb文件恢复表结构

    Mysql之如何根据.frm和.idb文件恢复表结构

    这篇文章主要介绍了Mysql之如何根据.frm和.idb文件恢复表结构问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • MySQL版本选择与安装超详细教程

    MySQL版本选择与安装超详细教程

    本文主要介绍了MySQL5.5和MySQL8.0的优点和缺点,并建议大多数用户使用最新的稳定版本,此外还提供了MySQL的安装教程和环境变量的配置方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-10-10
  • Linux下安装mysql-5.6.4 的图文教程

    Linux下安装mysql-5.6.4 的图文教程

    在开始安装前,先说明一下mysql-5.6.4与较低的版本在安装上的区别,从mysql-5.5起,mysql源码安装开始使用cmake了,因此当我们配置安装目录./configure --perfix=/.....的时候和以前的会有些区别,这点我们稍后会提到
    2013-06-06
  • MySQL数据库高可用HA实现小结

    MySQL数据库高可用HA实现小结

    MySQL数据库是目前开源应用最大的关系型数据库,有海量的应用将数据存储在MySQL数据库中,这篇文章主要介绍了MySQL数据库高可用HA实现,需要的朋友可以参考下
    2022-01-01

最新评论