MySQL、Oracle与SQLServer三大数据库语法全方位区别分析

来源:这里教程网 时间:2026-03-26 13:11:19 作者:
前言一、【最常用】分页查询(开发 TOP1 高频差异,必记)二、字符串处理(高频,拼接 / 长度 / 替换 / 截取,全部差异)三、日期 & 时间 操作(开发 TOP2 高频差异,函数完全不同)获取【当前系统时间】【重中之重】MySQLOracleSQLServer日期格式化(转指定格式字符串,开发必用)MySQLOracleSQLServer日期加减(增减年 / 月 / 日 / 时)MySQLOracleSQLServer主键自增(建表必备,语法完全不同)MySQLOracleSQLServer空值(NULL)处理(高频坑点,语法不同)核心规则MySQLOracleSQLServer总结 

前言

这三大数据库是开发 / 运维最常用的,核心 SQL92/99 标准语法通用select/from/where/group by/join/order by 等),差异集中在 函数、分页、字符串处理、日期操作、自增主键、语法细节、函数别名、空值处理 等高频开发场景,也是面试 / 项目迁移的高频考点,我按「开发常用分类」整理,条理清晰,方便查阅和复制,优先级从上到下,都是工作最常用的差异点

一、【最常用】分页查询(开发 TOP1 高频差异,必记)

分页是业务开发中使用频率最高的语法差异,三者写法完全不同,无通用方案,必须单独记忆!

MySQL

特有语法,使用 limit [起始索引], [条数]起始索引从 0 开始,极其简洁

-- 查询第11-20条数据(索引从0,跳过前10条,查10条) SELECT * FROM table_name LIMIT 10,10; -- 查询前10条数据(简写) SELECT * FROM table_name LIMIT 10;

Oracle

没有 limit 关键字,两种主流写法,Oracle 12c+ 支持新写法,低版本用子查询 + rownum(必须记)

-- 方式1:Oracle 12c及以上 推荐(简洁,类似MySQL),offset=起始行,fetch next=条数 SELECT * FROM table_name OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; -- 方式2:所有Oracle版本兼容(最常用),rownum是伪列,行号从1开始,必须套子查询 SELECT * FROM ( SELECT t.*, ROWNUM rn FROM table_name t WHERE ROWNUM <=20 ) WHERE rn >=11; -- 查询11-20条

SQLServer

两种写法,低版本用top+子查询,2012 及以上版本支持offset/fetch(和 Oracle 12c 一致)

-- 方式1:SQLServer2012+ 推荐,语法和Oracle 12c完全相同 SELECT * FROM table_name OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY; -- 方式2:所有版本兼容,TOP关键字(只能查前N条,分页需子查询) SELECT TOP 10 * FROM table_name; -- 查询前10条

二、字符串处理(高频,拼接 / 长度 / 替换 / 截取,全部差异)

字符串拼接 【开发必用】

这是最基础的高频差异,三者完全不同,90% 的语法报错都来自这里

MySQL

支持两种:CONCAT(str1,str2,...) 函数 或 ||(需开启配置),推荐 CONCAT 函数

SELECT CONCAT('姓名:',NAME,',年龄:',AGE) AS info FROM table_name;

Oracle

仅支持 || 拼接符,不支持 + 号;也支持 CONCAT 函数,但 Oracle 的 CONCAT只支持 2 个参数(多拼接必须嵌套 / 用 ||)

-- 推荐(最常用,无参数限制) SELECT '姓名:' || NAME || ',年龄:' || AGE AS info FROM table_name; -- 函数写法(仅2个参数) SELECT CONCAT('姓名:',NAME) AS info FROM table_name;

SQLServer

两种方式:+ 拼接符(最常用)、CONCAT(str1,str2,...) 函数(SQLServer2012+)

-- 推荐,简洁高效 SELECT '姓名:'+ NAME + ',年龄:'+ CAST(AGE AS VARCHAR) AS info FROM table_name; -- 函数写法(自动转换类型,无需CAST) SELECT CONCAT('姓名:',NAME,',年龄:',AGE) AS info FROM table_name;

注意:SQLServer 中,字符串和数字拼接必须用CAST/convert转类型,否则报错;MySQL/Oracle 自动转换。

其他高频字符串函数(通用名 + 差异写法)

功能MySQLOracleSQLServer说明字符串长度LENGTH(str)LENGTH(str)LEN(str)均返回字符长度转大写UPPER(str)UPPER(str)UPPER(str)完全通用转小写LOWER(str)LOWER(str)LOWER(str)完全通用去除首尾空格TRIM(str)TRIM(str)LTRIM(RTRIM(str))SQLServer 无 TRIM,需嵌套字符串截取SUBSTR(str,start,len)SUBSTR(str,start,len)SUBSTRING(str,start,len)通用,start 都从 1 开始字符串替换REPLACE(str,a,b)REPLACE(str,a,b)REPLACE(str,a,b)完全通用

三、日期 & 时间 操作(开发 TOP2 高频差异,函数完全不同)

日期是三大数据库差异最大的模块,函数名 / 语法完全不一样,无通用方案,高频考点 + 开发必记,按「常用操作」整理,最实用!

获取【当前系统时间】【重中之重】

MySQL

NOW() -- 推荐,返回 年月日 时分秒 (yyyy-MM-dd HH:mm:ss) SYSDATE() -- 系统当前时间,同NOW() CURDATE() -- 只返回 年月日 (yyyy-MM-dd) CURTIME() -- 只返回 时分秒 (HH:mm:ss)

Oracle

SYSDATE -- 推荐,返回 年月日 时分秒 (yyyy-MM-dd HH:mm:ss) 无括号! SYSTIMESTAMP -- 带毫秒的时间戳 TRUNC(SYSDATE) -- 只返回 年月日 (yyyy-MM-dd),截取日期部分

SQLServer

GETDATE() -- 推荐,返回 年月日 时分秒 (yyyy-MM-dd HH:mm:ss) CURRENT_TIMESTAMP -- 同GETDATE(),符合SQL标准 CAST(GETDATE() AS DATE) -- 只返回 年月日

日期格式化(转指定格式字符串,开发必用)

MySQL

DATE_FORMAT(日期字段, 格式符) ,格式符用 %Y/%m/%d/%H/%i/%s

SELECT DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s') AS now_time; -- 2026-01-13 16:30:59 SELECT DATE_FORMAT(NOW(),'%Y-%m-%d') AS now_date; -- 2026-01-13

Oracle

两种函数,TO_CHAR(日期,格式符) 最常用,格式符用 YYYY/MM/DD/HH24/MI/SS

SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') AS now_time FROM DUAL; -- 24小时制 SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD') AS now_date FROM DUAL;

注意:Oracle 的小时必须写HH24,否则是 12 小时制;必须加 FROM DUAL 伪表。

SQLServer

CONVERT(数据类型, 日期, 格式码) ,格式码是固定数字(记住常用的即可)

SELECT CONVERT(VARCHAR(20),GETDATE(),120) AS now_time; -- 2026-01-13 16:30:59 最常用 SELECT CONVERT(VARCHAR(10),GETDATE(),23) AS now_date; -- 2026-01-13 纯日期

日期加减(增减年 / 月 / 日 / 时)

MySQL

DATE_ADD(日期, INTERVAL 数值 单位) 或 直接用 日期 + INTERVAL

SELECT DATE_ADD(NOW(),INTERVAL 1 DAY) -- 当前时间+1天 SELECT NOW() - INTERVAL 1 MONTH -- 当前时间-1个月

Oracle

直接用 +/- 运算,日期是数值类型,1=1 天,1/24=1 小时

SELECT SYSDATE + 1 FROM DUAL; -- +1天 SELECT SYSDATE - 1/24 FROM DUAL;-- -1小时 SELECT ADD_MONTHS(SYSDATE, 1) FROM DUAL; -- 加1个月(专用函数)

SQLServer

DATEADD(单位, 数值, 日期) 函数,最规范

SELECT DATEADD(DAY,1,GETDATE()) -- +1天 SELECT DATEADD(MONTH,-1,GETDATE()) -- -1个月

主键自增(建表必备,语法完全不同)

业务表必备的主键自增,三大数据库实现方式完全不同,建表时必用,面试高频题

MySQL

建表时直接给字段加 AUTO_INCREMENT 属性,只支持主键自增,最简洁

CREATE TABLE t_user( id INT PRIMARY KEY AUTO_INCREMENT, -- 自增主键,插入时无需赋值 name VARCHAR(20) NOT NULL ); -- 插入时无需写id字段 INSERT INTO t_user(name) VALUES('张三');

Oracle

Oracle 11g 及以下 无自增关键字,必须通过【序列 + 触发器】实现自增;Oracle 12c+ 新增自增语法 GENERATED AS IDENTITY,兼容 MySQL 写法

-- Oracle12c+ 推荐写法(简洁) CREATE TABLE t_user( id INT PRIMARY KEY GENERATED AS IDENTITY, name VARCHAR2(20) NOT NULL ); -- Oracle11g及以下 传统写法(序列+触发器),必须创建两个对象 CREATE SEQUENCE seq_user_id START WITH 1 INCREMENT BY 1; -- 创建序列 -- 再创建触发器,插入时自动赋值主键 CREATE TRIGGER tri_user_id BEFORE INSERT ON t_user FOR EACH ROW BEGIN SELECT seq_user_id.NEXTVAL INTO :NEW.id FROM DUAL; END;

SQLServer

建表时给字段加 IDENTITY(起始值,步长) 属性,语法和 MySQL 类似,叫法不同

CREATE TABLE t_user( id INT PRIMARY KEY IDENTITY(1,1), -- 自增主键,1开始,每次+1 name VARCHAR(20) NOT NULL ); -- 插入时无需写id字段 INSERT INTO t_user(name) VALUES('张三');

空值(NULL)处理(高频坑点,语法不同)

开发中最容易踩坑的点:NULL 参与运算 / 判断时,结果永远是 NULL;三大数据库都有专用函数,函数名不同,必记

核心规则

NULL != ''NULL != 0,NULL 表示「无值」,不是空字符串 / 0;判断是否为 NULL 必须用 IS NULL/IS NOT NULL,不能用 = NULL/<> NULL(所有数据库通用)

空值替换函数(开发必用:NULL 替换为指定默认值)

MySQL

IFNULL(字段/表达式, 默认值)

-- 如果age为NULL,显示为0 SELECT IFNULL(age,0) AS age FROM t_user;

Oracle

NVL(字段/表达式, 默认值) ,Oracle 特有,无 IFNULL 函数

-- 如果age为NULL,显示为0 SELECT NVL(age,0) AS age FROM t_user;

SQLServer

ISNULL(字段/表达式, 默认值) ,和 MySQL 的 IFNULL 功能完全一样,只是函数名不同

-- 如果age为NULL,显示为0 SELECT ISNULL(age,0) AS age FROM t_user;

总结 

到此这篇关于MySQL、Oracle与SQLServer三大数据库语法全方位区别分析的文章就介绍到这了,

相关推荐

热文推荐