首页 > 数据库 > MySQL Server可执行注释

MySQL Server可执行注释

时间:2022-08-19 09:35:08浏览次数:60  
标签:语句 rocksdb GreatSQL Server 注释 sql MySQL

MySQL Server当前支持如下3种注释风格:

  • 以'# '开头的单行注释
  • 以'-- '开头的单行注释
  • C语言风格的单行/多行注释

如下sql脚本给出了3种注释风格的示例:

/* 这是一个
多行注释
示例
*/
select 1 from dual;
select 2 from dual; # 单行注释用例1
select 3 from dual; -- 单行注释用例2

可执行注释

为了支持在不同数据库之间的可移植性,MySQL Server针对C风格的注释在解析上做了一些扩展,当注释满足如下风格时,MySQL Server将会解析并执行注释中的代码:

/*! MySQL-specific code */

通过比较如下两个带注释的sql语句的执行结果可以比较直观地看出可执行注释语句的行为:

# 普通注释,'+1' 被忽略
mysql> select 1 /* +1 */;
+---+
| 1 |
+---+
| 1 |
+---+

# 可执行注释,'+1' 被当成语句的一部分
mysql> select 1 /*! +1 */;
+-------+
| 1  +1 |
+-------+
|     2 |
+-------+

借助这一特性,我们就有机会编写具备较好移植性的SQL语句, 在使MySQL独有特性的同时,保证了sql在其它数据库也能够成功被执行:

create table t1(col1 int) /*! engine=MyISAM */;
select /*! STRAIGHT_JOIN */ col1 from t1;
...

/*!version-number SQL*/

在日常使用中,我们还会经常看到如下格式的注释语句:

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE */
/*!80000 SET SESSION information_schema_stats_expiry=0 */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */

/*!跟的5位数字为版本指示器,其与数据库版本的对应规则为:

'/' '*' '!', followed by exactly
第1位:主版本号(VERSION_MAJOR), 
第2, 3位:小版本号(VERSION_MINOR),
第4, 5位:Patch号(VERSION_PATCH)
示例:
32302 -> 3.23.02
50738 -> 5.7.38
80025 -> 8.0.25

以上述第一个注释语句为例,它的含义可以描述为:当MySQL数据库版本为5.0.3或更高版本时,将SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE读取出来参与sql语法解析,并最终被执行;当MySQL版本低于5.0.3时,该行语句被当成一个普通的注释。不难看出,带version_number的可执行注释,是为了解决不同的MySQL版本之间的兼容问题。以8.0.23版本新增的Invisible Columnsw为例, 如下建表语句在8.0.23版本之前将无法执行:

CREATE TABLE t1 (i INT, j DATE INVISIBLE);

如下的语句改造则保证了建表语句的向下版本兼容:

CREATE TABLE t1 (i INT, j DATE /*!80023 INVISIBLE */);

实际上,在我们常用的工具mysqldump也借用这个特性,使得产生的sql能够兼容不同的数据库版本:

/*mysqldump 代码片段*/
   dump_fputs(
        sql_file,
        "/*!50717 SELECT COUNT(*) INTO @rocksdb_has_p_s_session_variables"
        " FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA ="
        " 'performance_schema' AND TABLE_NAME = 'session_variables'"
        " */;\n"
        "/*!50717 SET @rocksdb_get_is_supported = IF"
        " (@rocksdb_has_p_s_session_variables, 'SELECT COUNT(*) INTO"
        " @rocksdb_is_supported FROM performance_schema.session_variables"
        " WHERE VARIABLE_NAME=\\'rocksdb_bulk_load\\'', 'SELECT 0') */;\n"
        "/*!50717 PREPARE s FROM @rocksdb_get_is_supported */;\n"
        "/*!50717 EXECUTE s */;\n"
        "/*!50717 DEALLOCATE PREPARE s */;\n"
        "/*!50717 SET @rocksdb_enable_bulk_load = IF"
        " (@rocksdb_is_supported, 'SET SESSION rocksdb_bulk_load = 1',"
        " 'SET @rocksdb_dummy_bulk_load = 0') */;\n"
        "/*!50717 PREPARE s FROM @rocksdb_enable_bulk_load */;\n"
        "/*!50717 EXECUTE s */;\n"
        "/*!50717 DEALLOCATE PREPARE s */;\n");
    check_io(sql_file);

在show create table等语句中我们也能看到类似的应用(sql/sql_show.cc):

mysql> create table t1 (i int, j date invisible);
Query OK, 0 rows affected (0.03 sec)

mysql> show create table t1;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `i` int DEFAULT NULL,
  `j` date DEFAULT NULL /*!80023 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

结语

mysql server提供的可执行注释功能,在横向跨数据库和纵向跨版本兼容上都为数据库用户提供了较大支持,是一个比较便利的特性。功能实现上,mysql server是在词法解析阶段先对语句做了一遍拦截,针对/*!按具体情况做了特殊处理,如有兴趣您可以参考mysql的词法解析相关源码。注:以8.0.25版本为例,它的相关解析放在sql_lex.cc的lex_one_token()中,在其中您也能看见mysql词法解析器是怎么对optimizer hints comments(格式: /*+ optimizer_hints */ )进行处理的。


Enjoy GreatSQL

标签:语句,rocksdb,GreatSQL,Server,注释,sql,MySQL
From: https://www.cnblogs.com/greatsql/p/16600846.html

相关文章

  • powerdesigner16.5 连接MySQL8
    1.安装32位jdk。2.配置jdk路径:Tools-->GeneralOptions-->Variables修改JAR,JAVA,JAVAC,JAVADOC的Value3.连接数据库4.生成......
  • 【MySQL】SQL标准:SQL92、SQL99
    1.SQL标准SQL有两个主要的标准,分别是(1)SQL92:92年提出的标准规范,SQL92的形式更简单,但是写的SQL语句会比较长,可读性差。也被叫做SQL-2标准。(2)SQL99:相比于SQL92,语法更加复杂......
  • MySQL之Navicat和pymysql模块
    Navicat可视化软件下载安装官网地址:http://www.navicat.com.cn/主要功能介绍1.可以创建、管理和维护数据库2.可以充当各种数据库软件的客户端,并且提供操作数据库的快......
  • Navicat的使用与python中使用MySQL的基本方法
    Navicat的使用与python中使用MySQL的基本方法Navicat的下载及安装下载地址http://www.navicat.com.cn/download/navicat-premium由于navict的功能非常强大所以navic......
  • Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationExceptio
    多表查询时mysql语句报错Cause:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:Column'XX'inwhereclauseisambiguous原因多表查......
  • MySQL获取汉字的拼音首字母
    一、函数这里是通过函数调用进行获取汉字的拼音首字母。DELIMITER$$CREATEFUNCTION`pinyin`(P_NAMEVARCHAR(255))RETURNSvarchar(255)CHARSETutf8DETERMINIST......
  • 【8.18】MySQL数据库(5)
    学习内容概要Navicat可视化软件多表查询练习题python操作MySQL需要用到pymysql第三方模块SQL语法知识点补充了解as语法exist语法concat语法concat_ws......
  • python 操作mysql
    importpymysqldbinfo={"host":"192.16.8.x","post":3306,"user":"root","password":"xxxx","database":"xxx"} importpymysqlclassDBope......
  • 【PostgreSQL】连接到PostgreSQL Server
    连接pg需要指定以下的参数:·主机地址·端口·数据库名·用户·密码 如果没有指定上面的参数的话,pg会从环境变量中寻找以下的变量值:·PGHOST或PGHOSTADDR·PG......
  • 2022-8-17 mysql 第三天
    DQL查询语言子查询按照结果集的行列数不同,子查询可以分为以下几类:标量子查询:结果集只有一行一列(单行子查询)列子查询:结果集有一列多行行子查询:结果集有一行多列表子......