ORACLE、MYSQL、达梦 SQL 语法兼容性分析

SQL 语法兼容性分析

  • 一、标准函数替代实现兼容性
    • [1、使用 CASE WHEN 语法替代 DECODE 函数](#1、使用 CASE WHEN 语法替代 DECODE 函数)
    • [2、使用 CONCAT 函数替代 || 运算符](#2、使用 CONCAT 函数替代 || 运算符)
    • [3、使用 COALESCE 函数替代 NVL(Oracle/达梦)和 IFNULL(MySQL)](#3、使用 COALESCE 函数替代 NVL(Oracle/达梦)和 IFNULL(MySQL))
    • [4、使用 CONCAT(x, '') 替代 TO_CHAR 函数实现数值型转字符串](#4、使用 CONCAT(x, '') 替代 TO_CHAR 函数实现数值型转字符串)
    • [5、使用 CAST(x AS VARCHAR(n)) 替代 TO_CHAR 函数实现数值型转字符串](#5、使用 CAST(x AS VARCHAR(n)) 替代 TO_CHAR 函数实现数值型转字符串)
  • 二、不能完全兼容的函数

一、标准函数替代实现兼容性


1、使用 CASE WHEN 语法替代 DECODE 函数

ORACLE、MYSQL、达梦均支持 CASE WHEN,但 MYSQL 不支持 DECODE 函数

数据库 是否支持 DECODE 函数 是否支持 CASE WHEN 语法
Oracle ✅ 支持 ✅ 支持
MySQL 不支持 ✅ 支持
达梦 ✅ 支持 ✅ 支持
sql 复制代码
DECODE(B.FLAG,'0','未完成','1','已完成') FLAGNAME
sql 复制代码
CASE B.FLAG
    WHEN '0' THEN '未完成'
    WHEN '1' THEN '已完成'
END FLAGNAME

2、使用 CONCAT 函数替代 || 运算符

数据库 是否支持连接运算符 是否支持 CONCAT 函数 差异
Oracle ✅ 支持 ✅ 支持 ⚠️CONCAT 函数最多只允许两个参数
MySQL 不支持 ✅ 支持 CONCAT 函数支持两个或以上参数
达梦 ✅ 支持 ✅ 支持 ⚠️CONCAT 函数最多只允许两个参数
sql 复制代码
# 连接两个字符串
SELECT CONCAT('Hello', 'World') FROM DUAL;

# ORACLE、达梦通过嵌套实现连接多个字符串
SELECT CONCAT(CONCAT('A', 'B'), 'C') FROM DUAL;
sql 复制代码
# ORACLE、达梦通过 || 运算符实现连接多个字符串
SELECT 'A' || 'B' || 'C' || 'D' FROM DUAL;

3、使用 COALESCE 函数替代 NVL(Oracle/达梦)和 IFNULL(MySQL)

复制代码
COALESCE 是 SQL 标准中定义的函数,用于返回参数列表中第一个非空(NOT NULL) 的值。如果所有参数都为 NULL,则返回 NULL。
数据库 是否支持 NVL 函数 是否支持 IFNULL 函数 是否支持 COALESCE 函数
Oracle ✅ 支持 不支持 ✅ 支持
MySQL 不支持 ✅ 支持 ✅ 支持
达梦 ✅ 支持 不支持 ✅ 支持
sql 复制代码
SELECT COALESCE(NULL, NULL, '第一个非空值', '第二个非空值') AS result FROM DUAL;
sql 复制代码
SELECT NVL(phone, NVL(telephone, NVL(default_contact, '暂无联系方式'))) AS contact FROM users;
SELECT IFNULL(phone, IFNULL(telephone, IFNULL(default_contact, '暂无联系方式'))) AS contact FROM users;

4、使用 CONCAT(x, '') 替代 TO_CHAR 函数实现数值型转字符串

数据库 是否支持 TO_CHAR 函数
Oracle ✅ 支持
MySQL 不支持
达梦 ✅ 支持
sql 复制代码
SELECT CONCAT(1.012300, '') FROM DUAL

5、使用 CAST(x AS VARCHAR(n)) 替代 TO_CHAR 函数实现数值型转字符串

  • 使用时必须指定字符串长度
  • ORACLE 也能识别 CAST 中的 VARCHAR 关键字
sql 复制代码
CAST(ROLE.ROLE_CODE AS VARCHAR(50))

二、不能完全兼容的函数

1、日期格式化函数

数据库 TO_CHAR(CREATETIME, 'yyyy-mm-dd hh24:mi:ss') DATE_FORMAT(CREATEDATETIME, '%Y-%m-%d %H:%i:%s')
Oracle ✅ 支持 不支持
MySQL 不支持 ✅ 支持
达梦 ✅ 支持 不支持

推荐解决方案:在应用层(Java)处理日期格式化

数据库 TO_DATE(str, 'YYYY-MM-DD HH24:MI:SS') STR_TO_DATE(str, '%Y-%m-%d %H:%i:%s')
Oracle ✅ 支持 不支持
MySQL 不支持 ✅ 支持
达梦 ✅ 支持 不支持

推荐解决方案:应用层传 Date 或 LocalDateTime 类型参数

2、WM_CONCAT、LISTAGG 和 GROUP_CONCAT

数据库 WM_CONCAT GROUP_CONCAT LISTAGG
Oracle ⚠️已废弃,不推荐使用 不支持 ✅ 支持
MySQL 不支持 ✅ 支持 不支持
达梦 ⚠️不推荐使用 ⚠️默认不支持 ✅ 支持

WM_CONCAT 不支持排序,拼接顺序不确定。默认使用逗号分隔符拼接,不能自定义分隔符。

sql 复制代码
SELECT dept_id,
       WM_CONCAT(emp_name) AS names
FROM employee
GROUP BY dept_id;

LISTAGG 支持排序,支持自定义分隔符。

sql 复制代码
SELECT dept_id,
       LISTAGG(emp_name, ',') WITHIN GROUP (ORDER BY emp_name) AS names
FROM employee
GROUP BY dept_id;

GROUP_CONCAT 支持排序,支持自定义分隔符。

sql 复制代码
SELECT dept_id,
       GROUP_CONCAT(emp_name ORDER BY emp_name SEPARATOR ',') AS names
FROM employee
GROUP BY dept_id;

推荐解决方案:在应用层(Java)处理聚合

相关推荐
JavaPub-rodert20 小时前
Go 后台如何同时兼容 MySQL、PostgreSQL、SQLite 和 SQL Server?从 ShiyuAdmin 看 GORM 多数据库适配
数据库·mysql·postgresql·golang·javapub·王仕宇
瀚高PG实验室20 小时前
SQL优化案例:存储过程、复杂SQL拆成简单SQL提升整体性能
数据库·sql·postgresql·瀚高数据库
爱吃火鸡面呀21 小时前
MySQL 查询与函数详解:从基础条件筛选到高级字符处理
数据库·mysql
知行产研1 天前
中国矿山无人驾驶出海的三重门
数据库·mysql·php
爱和冰阔落1 天前
【MySQL 慢查询排查实战】列表接口逐渐变慢时,怎样从请求链路定位原因
android·数据库·mysql
Dxy12393102161 天前
MySQL有哪些锁?InnoDB锁体系完整梳理博客
数据库·mysql
wear工程师1 天前
MySQL 索引条件下推是什么?Using index condition 并不是覆盖索引
sql·mysql
蒸蒸yyyyzwd1 天前
cpp选手秋招学习笔记 day12
笔记·学习·oracle
方便面不加香菜1 天前
MySQL 复合查询
数据库·mysql
花花鱼1 天前
MySQL Illegal mix of collations 全解|字符集与排序规则冲突原理、分层排错、通用解决方案(适配5.7/8.0迁移)
数据库·mysql