MySQL学习-SQL Mode

MySQL服务器可以工作在不同的SQL模式下,并能够针对不同客户端以不同的方式应用这些模式。这样,应用程序就能够对服务器操作进行量身定制以满足需求。这类模式定义了MySQL应支持的SQL语法,以及应该在数据上执行何种确认检查,这样就能在众多不同环境下与其他数据库服务器一起更便捷使用MySQL。

在MySQL中主要用它来解决如下几类问题:

1、通过设置SQL Mode,可以完成不同严格程度的数据校验,有效保障数据准确性;

2、通过设置SQL Mode为ANSI模式,来保证大多数SQL符合标准SQL语法,这样应用在不同数据库之间迁移时,不需要对业务SQL进行大量修改;

3、与第二点类似,可以在数据库进行迁移时更加方便


我的mysql学习版本为5.7,所以接下来的内容都是基于mysql5.7的。

常用SQL Model:

SQL_Mode值 描述
ANSI 

等同REAL_AS_FLOAT,PIPES_AS_CONCAT

,ANSI_QUOTES,IGNORE_SPACE和ANSI组合模式

STRICT_TRANS_TABLES 适用于事务表和非事务表,它是严格模式
TRADITIONAL

等同于STRICT_TRANS_TABLES,STRICT_ALL_TABLES

,NO_ZERO_IN_DATE,NO_ZERO_DATE,

ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL和

NO_AUTO_CREATE_USER组合模式


查看SQL Mode

select @@sql_model

上述所代表的意思分别如下:

ONLY_FULL_GROUP_BY:不要让GROUP BY中的查询指向未选择的列;


当我去掉该选项之后,如上图便可以group by不在查询中的列。

STRICT_TRANS_TABLES:如果不能将给定的值插入到事务表中,则放弃该语句,对于非事务表,如果值出现在单行语句或多行语句中的第一行,则放弃该语句。

注:mysql的严格模式就是sql_mode启用了STRICT_TRANS_TABLES的模式。

NO_ZERO_IN_DATE:在严格模式,不接受月或日部分为0的日期;

NO_ZERO_DATE:在严格模式下,不要将'0000-00-00'作为合法日期;

ERROR_FOR_DIVISION_BY_ZERO:在严格模式下,在insert和update过程中,如果被0除或者MOD(x,0)则会产生错误,如果未给出该模式,则被0除时返回null,如果用到insert ignore或者update ignore中,则会生成被0除警告,操作结果为null;

NO_AUTO_CREATE_USER:防止GRANT自动创建新用户,除非指定了密码;

NO_ENGINE_SUBSTITUTION:如果需要的存储引擎被禁用或者未编译,可以防止自动替换存储引擎。


如何去设置sql_mode

SET [SESSION|GLOBAL] sql_mode='modes'

如果使用session则是对当前会话窗口用户当前有效;global则是全局有效


SQL MODE常见功能:

1、校验日期合法性

我们先使当前会话的sql_mode为ANSI,ANSI是使其更符合标准SQL

在我们往数据表插入数据包含日期'2018-05-32'时,他能够插入数据但是显示的会更改为如下:

显然,在ANSI模式下,非法日期可以被插入,值变成'0000-00-00 00:00:00'而已,并报警告


2、使反斜线成为普通字符:

 该功能需要开启NO_BACKSLASH_ESCAPES模式,如下图是没有开启时插入数据:


可以看到字符串banco的b被转义了,当我们去设置开启该模式时:



3、将||视为连接字符串操作符:

在oracle等数据库中,||被视作字符串连接操作符,为了迁移时能够更加便捷,所以MySQL加上PIPES_AS_CONCAT模式



其他的sql_mode模式:

ALLOW_INVALID_DATES:在严格模式下不要检查全部日期。只检查1到12之间的月份和1到31之间的日。这在Web应用程序中,当你从三个不同的字段获取年、月、日,并且想要确切保存用户插入的内容(不进行日期验证)时很重要。该模式适用于DATE和DATETIME列。不适合TIMESTAMP列,TIMESTAMP列需要验证日期。

启用严格模式后,服务器需要合法的月和日,不仅仅是分别在1到12和1到31范围内。例如,禁用严格模式时'2004-04-31'是合法的,但启用严格模式后是非法的。要想在严格模式允许遮掩固定日期,还应启用ALLOW_INVALID_DATES。

ANSI_QUOTES:将‘"’视为识别符引号(‘`’引号字符),不要视为字符串的引号字符。在ANSI模式,你可以仍然使用‘`’来引用识别符。启用ANSI_QUOTES后,你不能用双引号来引用字符串,因为它被解释为识别符。

 HIGH_NOT_PRECEDENCE:NOT操作符的优先顺序是表达式例如NOT a BETWEEN b AND c被解释为NOT (a BETWEEN b AND c)。在一些旧版本MySQL中, 表达式被解释为(NOT a) BETWEEN b AND c。启用HIGH_NOT_PRECEDENCESQL模式,可以获得以前的更高优先级的结果。

 IGNORE_SPACE:允许函数名和‘(’之间有空格。强制将所有函数名视为保存的字。结果是,如果你想要访问保存为字的数据库、表或列名,你必须引用它。例如,因为有USER()函数,mysql数据库中的user表名和该表内的User列被保存下来,因此你必须引用它们:select 'User' from mysql.'user';

NO_AUTO_VALUE_ON_ZERO:它影响AUTO_INCREMENT列的处理。一般情况,你可以向该列插入NULL或0生成下一个序列号。NO_AUTO_VALUE_ON_ZERO禁用0,因此只有NULL可以生成下一个序列号。

NO_DIR_IN_CREATE:创建表时,忽视所有INDEX DIRECTORY和DATA DIRECTORY指令。该选项对从复制服务器有用。

NO_FIELD_OPTIONS:不要在SHOW CREATE TABLE的输出中打印MySQL专用列选项。该模式在可移植模式(portability mode)下用于mysqldump。

 NO_KEY_OPTIONS:不要在SHOW CREATE TABLE的输出中打印MySQL专用索引选项。该模式在可移植模式(portability mode)下用于mysqldump

NO_TABLE_OPTIONS:不要在SHOW CREATE TABLE的输出中打印MySQL专用表选项(例如ENGINE)。该模式在可移植模式(portability mode)下用于mysqldump

 NO_UNSIGNED_SUBTRACTION:在减运算中,如果某个操作数没有符号,不要将结果标记为UNSIGNED。请注意这样使UNSIGNED BIGINT不能100%用于上下文中。

REAL_AS_FLOAT:将REAL视为FLOAT的同义词,而不是DOUBLE的同义词。


猜你喜欢

转载自blog.csdn.net/m0_37752084/article/details/80207133