MySQL 中什么是条件注释

很多同学写 SQL 的时候,都熟悉 #、--、/* */ 这几种普通注释。普通注释的特点很简单:数据库解析时直接忽略里面的内容,不会执行。

但 MySQL 里有一类特殊注释,在 MySQL 环境下注释内部的 SQL 会被执行;其他数据库(Oracle、PostgreSQL)会当成普通注释直接跳过 ,这就是 MySQL 条件注释,也常被叫做版本注释、可执行注释。

一句话总结:条件注释是 MySQL 提供的,用来做跨数据库、跨版本 SQL 兼容的语法。

一、基础语法

sql 复制代码
/*! 这里写MySQL才会执行的SQL语句 */

格式:/*! 开头,*/ 结尾。

  • MySQL:会把 /*! 和 */ 中间的内容当做正常SQL执行
  • 其他数据库:识别为普通多行注释,直接忽略,不会报错

带版本号的条件注释(最常用)

还可以在 ! 后面加上版本号,代表只有MySQL版本大于等于指定版本时,才执行内部SQL

sql 复制代码
/*!40101 SET NAMES utf8mb4 */;

解读:

  • 40101 = 4.1.01 版本
  • MySQL >=4.1.01 时,执行 SET NAMES utf8mb4
  • 版本低于该值 或者 非MySQL数据库,当作注释忽略

版本号规则:主版本*10000 + 次版本*100 + 修订号

示例:

  • 8.0.26 → 80026
  • 5.7.36 → 50736

二、简单示例演示

示例1:基础条件注释

sql 复制代码
-- 普通SQL
SELECT 1;
/*! SELECT 2; */

在MySQL执行,会返回两个结果集:1 和 2;

如果放到PostgreSQL执行,只会执行 SELECT 1,SELECT 2 被当成注释跳过。

示例2:版本控制,仅高版本执行

sql 复制代码
/*!80000 CREATE TABLE IF NOT EXISTS test_v8(id int) */;

含义:MySQL版本 ≥8.0.00 才会创建这张表,5.7及更早版本不执行。

我们经常导出mysqldump备份文件时,里面大量出现这种语法,这也是条件注释最典型的使用场景。打开dump文件就能看到大量 /*!40xxx ... */。

三、典型使用场景

  1. mysqldump导出备份
    mysqldump 默认大量使用条件注释。导出的SQL脚本可以在不同版本MySQL导入,同时拿到其他数据库也不会因为MySQL特有语法报错。比如设置字符集、关闭外键检查等语句。
sql 复制代码
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
  1. 跨数据库兼容脚本
    一份SQL脚本,同时兼容MySQL和其他数据库。特有语法写在条件注释里。
    例如:只有MySQL支持的 LIMIT,其他数据库不支持,就可以这样写:
sql 复制代码
SELECT * FROM user
/*! LIMIT 10 */;

在PostgreSQL执行不会识别LIMIT,不会执行这部分;MySQL会正常执行limit。

  1. 版本平滑适配
    新特性只在高版本MySQL启用,低版本跳过。比如MySQL8.0支持的窗口函数、新的排序规则,用版本条件注释包裹,一份脚本兼容5.7和8.0。

四、容易踩的坑

  1. 注释内部语法错误依然会报错
    条件注释不是"屏蔽错误",MySQL满足版本条件后,会直接解析里面的SQL。如果里面SQL写错,一样抛出异常。
sql 复制代码
/*!80000 SELEC 1 */; -- 拼写错误,8.0环境直接报语法错误
  1. 不要和普通多行注释混淆

    /* 内容 */:所有数据库都是注释,永远不执行。

    /*! 内容 */:MySQL会执行,其他库忽略。差别就在于那个感叹号。

  2. 版本号写错,逻辑完全反转

    版本号是大于等于才执行。如果你写 /*!50700 ... */,在MySQL8.0环境依旧会执行,80000>50700。

  3. 不适合业务代码大量滥用

    条件注释适合迁移脚本、备份脚本。业务系统里SQL尽量不要大量依赖这个语法,可读性差,维护成本高。ORM框架一般不会推荐大量使用。

五、补充:反向理解

很多人第一次看到mysqldump里面的 /*!40000 DROP TABLE IF EXISTS ... */ 很疑惑,以为是注释。

其实这是MySQL专门设计的兼容语法,为了让一份SQL脚本具备多环境兼容性,是MySQL生态里很经典的设计。

小结

MySQL条件注释 /*! [版本] sql */,核心能力一句话:

一份SQL,在MySQL中可选择性执行内部语句,其它数据库自动忽略这段代码,用于版本适配、跨库脚本兼容。

它不是普通注释,是MySQL独有的编译期条件执行语法,最常见于mysqldump导出文件。日常业务SQL尽量少用,但是做数据库迁移、脚本分发的时候,这个特性就非常好用。

相关推荐
可乐鸡翅yeah_1 小时前
AES‑128 加密 M3U8,IV 初始化向量新手容易踩坑
前端·网络·数据库·ffmpeg·音视频·m3u8在线
IvorySQL1 小时前
PostgreSQL 日报| relchecks 溢出导致表无法删除(9 月 28 日)
数据库·人工智能·ai·postgresql·区块链
帷幕落秋1 小时前
Redis主从复制
运维·数据库
帷幕落秋1 小时前
Mysql主从复制
运维·数据库
暖核1 小时前
MySQL 高级运维核心:备份恢复、主从复制与 MHA 高可用复习总结
运维·数据库·mysql
晚风叙码3 小时前
MySQL 表的操作:从建表到删表,一篇讲清楚
android·mysql·oracle
paopaokaka_luck3 小时前
非遗文物数字化小程序(AI非遗问答、ONNX图像识别、协同过滤推荐、ECharts数据分析、非遗知识浏览与互动、文创商城订单闭环、文化活动报名签到、社区交流)
javascript·spring boot·mysql·数据分析·echarts·mybatis
加油yx4 小时前
数据库基础
数据库
天桥下的卖艺者4 小时前
chrals.CTI函数升级版发布,增加了CTI衍生的脂肪指数提取
数据库·r语言