MySQL Server可以以不同的SQL模式运行,并且可以针对不同的客户端以不同的方式应用这些模式,具体取决于该模式sql_mode.
系统变量。dba可以设置全局SQL模式以匹配站点服务器的运行需求,每个应用程序可以将其会话SQL模式设置为自己的需求。
模式影响MySQL支持的SQL语法和它执行的数据验证检查。这使得在不同的环境中使用MySQL以及与其他数据库服务器一起使用MySQL变得更加容易。
InnoDB表,考虑也
innodb_strict_mode
系统变量。它启用额外的错误检查InnoDB
表。MySQL 5.7中的默认SQL模式包括以下模式:
ONLY_FULL_GROUP_BY
,STRICT_TRANS_TABLES
,no_zero_in_date.
,NO_ZERO_DATE
,ERROR_FOR_DIVISION_BY_ZERO
,NO_AUTO_CREATE_USER
,no_engine_substitut
。这些模式被添加到MySQL 5.7的默认SQL模式中
ONLY_FULL_GROUP_BY
和STRICT_TRANS_TABLES
在MySQL 5.7.5中添加了模式。的NO_AUTO_CREATE_USER
MySQL 5.7.7中增加了mode。的ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
mode是在MySQL 5.7.8中添加的。有关对默认SQL模式值的这些更改的其他讨论,请参见——sql模式= "
选项,或模式
”SQL-Mode =“
在选项文件中模式
”my.cnf
(Unix操作系统)my.ini
(Windows)。模式
是由逗号分隔的不同模式的列表。要明确清除SQL模式,请将其设置为空字符串使用--sql-mode =“”
或SQL-Mode =“”
在一个选项文件中。笔记MySQL安装程序可能会在安装过程中配置SQL模式。如果SQL模式与默认模式或您期望的模式不同,请检查服务器在启动时读取的选项文件中的设置。
要在运行时更改SQL模式,请设置全局或会话
sql_mode.
使用集
声明:设置全局SQL_Mode ='模式'设置会话SQL_MODE ='模式'
设置
全球
变量需要极好的
权限,并影响从那时起连接的所有客户端的操作。设置会话
变量只影响当前客户端。每个客户机都可以更改其会话sql_mode.
价值随时。确定当前全局或会话
sql_mode.
设置,选择其值:选择@@GLOBAL.sql_mode;选择@@SESSION.sql_mode;
重要的SQL模式和用户定义分区。在将数据创建和插入到分区表之后更改服务器SQL模式可能会导致此类表的行为发生重大变化,并可能导致数据丢失或损坏。在使用用户定义的分区创建了表之后,强烈建议您永远不要更改SQL模式。
复制分区表时,源和副本上的不同SQL模式也可能导致问题。为获得最佳结果,您应该始终在源和副本上使用相同的服务器SQL模式。
有关更多信息,请参见
最重要的是
sql_mode.
这些值可能是:这种模式改变语法和行为以更接近标准SQL。这是一个特别的
如果不能按照给定的方式将值插入事务表中,则终止该语句。对于非事务表,如果该值出现在单行语句或多行语句的第一行中,则中止该语句。本节稍后将提供更多细节。
从MySQL 5.7.5开始,默认的SQL模式包括
STRICT_TRANS_TABLES
。使MySQL的行为像”传统的”SQL数据库系统。对这种模式的简单描述是”给出一个错误而不是警告”在列中插入不正确的值时。这是一个特别的
笔记与
传统的
启用模式,一个插入
或更新
发生错误后,中止。如果您使用的是非讲的存储引擎,这可能不是您想要的,因为在错误之前所做的数据更改可能不会回滚,从而导致”部分完成”更新。
当本手册引用时”严格模式,”它意味着一个或两者的模式
STRICT_TRANS_TABLES
或STRICT_ALL_TABLES
启用。下面列出了所有支持的SQL模式:
不要对日期进行全面检查。只能确认月的取值范围是1 ~ 12,日的取值范围是1 ~ 31。这对于在三个不同字段中获取年、月和日并准确存储用户插入的内容(不需要日期验证)的Web应用程序可能很有用。此模式适用于
日期
和DATETIME
列。它并不适用时间戳
列,始终需要有效日期。与
ALLOW_INVALID_DATES
禁用,服务器要求分别为合法的月份和日本值,而不仅仅在1到12和1到31范围内。禁用严格模式,日期无效“2004-04-31”
转换为“0000-00-00”
并产生一个警告。启用严格模式后,无效日期将产生错误。允许这样的日期,使能ALLOW_INVALID_DATES
。治疗
”
作为标识符报价字符(如”
引用字符)而不是字符串报价字符。你仍然可以使用”
启用此模式时引用标识符。与ANSI_QUOTES.
启用后,不能使用双引号引用字符串字面量,因为它们被解释为标识符。的
ERROR_FOR_DIVISION_BY_ZERO
模式影响分割的处理零,包括国防部(
。数据更改操作(N
, 0)插入
,更新
),其效果还取决于是否启用了严格SQL模式。如果未启用此模式,则按零插入划分
零
并没有产生警告。如果启用此模式,则按零插入划分
零
并产生警告。如果启用此模式和严格模式,则除零会产生错误,除非
忽略
也给出了。为插入忽略
和更新忽略
,除以零插入零
并产生警告。
为
选择
,除以零返回零
。启用ERROR_FOR_DIVISION_BY_ZERO
也会产生一个警告,无论是否启用了严格模式。ERROR_FOR_DIVISION_BY_ZERO
弃用。ERROR_FOR_DIVISION_BY_ZERO
不是严格模式的一部分,但应该与严格模式一起使用,并在默认情况下启用。如果ERROR_FOR_DIVISION_BY_ZERO
已启用而不实现严格的模式,反之亦然。有关其他讨论,请参阅ERROR_FOR_DIVISION_BY_ZERO
弃用;在MySQL的未来版本中,它将作为一个单独的模式名被删除,其效果包括在严格SQL模式的效果中。的优先级
不
操作符是这样的表达式,如不是a在b和c之间
被解析为NOT (a BETWEEN b AND c)
。在一些旧版本的MySQL中,表达式被解析为(不是a)在b和c之间
。旧的优先级更高的行为可以通过启用HIGH_NOT_PRECEDENCE
SQL模式。mysql> SET sql_mode = ";mysql> SELECT NOT 1 BETWEEN -5 AND 5;-> 0 mysql> SET sql_mode = 'HIGH_NOT_PRECEDENCE';mysql> SELECT NOT 1 BETWEEN -5 AND 5;- > 1
允许函数名和
(
特点。这会导致内置的函数名称被视为保留字。结果,必须引用与功能名称相同的标识符如下引用COUNT ()
功能、用途数数
作为以下语句中的表名导致错误:mysql> CREATE TABLE count (i INT);错误1064(42000):您有一个错误在您的SQL语法
应引用表名:
mysql> CREATE TABLE ' count ' (i INT);查询OK, 0行受影响(0.00秒)
的
Ignore_space.
SQL模式适用于内置函数,而不是对用户定义的函数或存储功能。无论是如何的,始终允许在udf或存储的函数名称之后拥有空格Ignore_space.
启用。以便进一步讨论
Ignore_space.
,请参阅防止
授予
语句来自动创建新用户帐户(除非指定了身份验证信息)。语句必须使用非空密码确认的
或者使用认证插件确定
。它最好使用mysql帐户
创建用户
而不是授予
。NO_AUTO_CREATE_USER
已弃用,默认SQL模式包括NO_AUTO_CREATE_USER
。分配给sql_mode.
这一变化的NO_AUTO_CREATE_USER
模式状态会产生警告,但设置的赋值除外sql_mode.
来默认
。预计NO_AUTO_CREATE_USER
将在MySQL的未来版本中被删除,并且它的效果将一直被启用授予
不再创建帐户)。之前,之前
NO_AUTO_CREATE_USER
被推翻,一个原因不启用它是它不是安全的。现在它可以启用和复制安全用户管理如果不存在,请创建用户
,删除用户如果存在
,Alter user if exists
而不是授予
。当副本可能具有与源上的副本不同的授权时,这些语句将启用安全复制。看到NO_AUTO_VALUE_ON_ZERO
影响处理AUTO_INCREMENT
列。通常,您可以通过插入列来为列生成下一个序列号零
或0
进去。NO_AUTO_VALUE_ON_ZERO
抑制这种行为0
所以,只有零
生成下一个序列号。这种模式很有用,如果
0
已存储在一个表的AUTO_INCREMENT
列。(存储0
顺便说一下,这不是一个推荐的做法。)例如,如果您转储表,mysqldump然后重新加载,MySQL通常会在遇到0
值,从而生成一个内容与转储的内容不同的表。启用NO_AUTO_VALUE_ON_ZERO
在重新加载转储文件之前解决了这个问题。由于这个原因,,mysqldump自动在其输出中包含启用的语句NO_AUTO_VALUE_ON_ZERO
。启用此模式会禁用反斜杠字符的使用(
\
)作为字符串和标识符中的转义字符。通过启用此模式,Backslash成为与其他任何其他字符相似的普通字符,以及默认转义序列就像
表达式被更改,因此不使用转义字符。创建表时,忽略all
索引目录
和数据目录
指令。此选项对副本复制服务器很有用。类语句时,控制默认存储引擎的自动替换
创建表
或ALTER TABLE
指定禁用或未编译的存储引擎。默认情况下,
no_engine_substitut
启用。由于存储引擎可以在运行时可插入,因此不可用的引擎相同的方式处理:
与
no_engine_substitut
残疾,创建表
使用默认引擎,如果需要的引擎不可用,将会出现警告。为ALTER TABLE
,则会出现警告,并且不会更改表。与
no_engine_substitut
如果启用,则会发生错误,如果所需的引擎不可用,则不会创建或修改表。的输出中不打印mysql特定的列选项
显示创建表
。此模式由,mysqldump在便携性模式。笔记截至MySQL 5.7.22,
NO_FIELD_OPTIONS
弃用。在MySQL 8.0中被删除。的输出中不打印mysql特定的索引选项
显示创建表
。此模式由,mysqldump在便携性模式。笔记截至MySQL 5.7.22,
NO_KEY_OPTIONS
弃用。在MySQL 8.0中被删除。不打印特定于mysql的表选项(例如
引擎
)的输出显示创建表
。此模式由,mysqldump在便携性模式。笔记截至MySQL 5.7.22,
NO_TABLE_OPTIONS
弃用。在MySQL 8.0中被删除。整数值之间的减法,其中一个类型
无符号
,默认情况下生成无符号结果。如果结果是负数,则会产生一个错误:mysql> SET sql_mode = ";mysql> SELECT CAST(0 AS UNSIGNED) - 1;ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as UNSIGNED) - 1)'
如果是
NO_UNSIGNED_SUBTRACTION
SQL模式已启用,结果为负:mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';mysql> SELECT CAST(0 AS UNSIGNED) - 1;+-------------------------+ | 作为无符号(0)- 1 | +-------------------------+ | - 1 | +-------------------------+
如果该操作的结果用于更新
无符号
整型列,结果将被剪辑到列类型的最大值,或者如果被剪辑到0NO_UNSIGNED_SUBTRACTION
启用。启用严格的SQL模式后,会出现错误,列保持不变。当
NO_UNSIGNED_SUBTRACTION
启用后,减法结果已签名,即使任何操作数都没有符合。例如,比较列的类型C2.
在表t1
和柱状图一样C2.
在表t2
:mysql> set sql_mode ='';MySQL>创建表测试(C1 Bigint unsigned not null);MySQL>创建表T1从测试中选择C1 - 1作为C2;mysql>描述t1;+ ------- + ------------------------------------- + ------- + |领域|型号null |钥匙|默认 Extra | +-------+---------------------+------+-----+---------+-------+ | c2 | bigint(21) unsigned | NO | | 0 | | +-------+---------------------+------+-----+---------+-------+ mysql> SET sql_mode='NO_UNSIGNED_SUBTRACTION'; mysql> CREATE TABLE t2 SELECT c1 - 1 AS c2 FROM test; mysql> DESCRIBE t2; +-------+------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------------+------+-----+---------+-------+ | c2 | bigint(21) | NO | | 0 | | +-------+------------+------+-----+---------+-------+
这意味着
Bigint unsigned.
在所有上下文中都没有100%。看到的
NO_ZERO_DATE
模式影响服务器是否允许“0000-00-00”
作为有效日期。其效果还取决于是否启用了严格的SQL模式。如果未启用此模式,
“0000-00-00”
是允许的,插入不会产生警告。如果启用此模式,
“0000-00-00”
允许并插入发出警告。如果启用此模式和严格模式,
“0000-00-00”
是不允许的,插入会产生错误,除非忽略
也给出了。为插入忽略
和更新忽略
,“0000-00-00”
允许并插入发出警告。
NO_ZERO_DATE
弃用。NO_ZERO_DATE
不是严格模式的一部分,但应该与严格模式一起使用,并在默认情况下启用。如果NO_ZERO_DATE
已启用而不实现严格的模式,反之亦然。有关其他讨论,请参阅NO_ZERO_DATE
弃用;在MySQL的未来版本中,它将作为一个单独的模式名被删除,其效果包括在严格SQL模式的效果中。的
no_zero_in_date.
模式影响服务器是否允许年份部分不为零但月或日部分为0的日期。(此模式影响日期,如'2010-00-01'
或“2010-01-00”
,但不“0000-00-00”
。控制服务器是否允许“0000-00-00”
,可以使用NO_ZERO_DATE
模式)。的影响no_zero_in_date.
也取决于是否启用了严格的SQL模式。如果不启用此模式,则允许日期为零,插入不会产生警告。
如果启用此模式,则将带有零部件的日期插入为
“0000-00-00”
并发出警告。如果启用此模式和严格模式,则不允许有零部件的日期,插入会产生错误,除非
忽略
也给出了。为插入忽略
和更新忽略
,零部分的日期插入为“0000-00-00”
并发出警告。
no_zero_in_date.
弃用。no_zero_in_date.
不是严格模式的一部分,但应该与严格模式一起使用,并在默认情况下启用。如果no_zero_in_date.
已启用而不实现严格的模式,反之亦然。有关其他讨论,请参阅no_zero_in_date.
弃用;在MySQL的未来版本中,它将作为一个单独的模式名被删除,其效果包括在严格SQL模式的效果中。拒绝选择列表、
有
条件,或命令
列表引用未被命名的非聚合列集团
子句在功能上也不依赖于(唯一由)集团
列。从MySQL 5.7.5开始,默认的SQL模式包括
ONLY_FULL_GROUP_BY
。(在5.7.5之前,MySQL没有检测到功能依赖性和ONLY_FULL_GROUP_BY
默认不启用。关于5.7.5之前行为的描述,请参见MySQL 5.6参考手册。)对标准SQL的MySQL扩展允许在
有
子句添加到选择列表中的别名表达式。MySQL 5.7.5之前,启用ONLY_FULL_GROUP_BY
禁用此扩展,因此需要有
使用无别名表达式编写的子句。从MySQL 5.7.5开始,这个限制被取消了有
子句可以引用别名,而不管是否ONLY_FULL_GROUP_BY
启用。默认情况下,尾随空格被从
字符
检索时的列值。如果pad_char_to_full_length.
是否启用,则不进行修整和检索字符
值被完整地填充。此模式不适用于VARCHAR
列,检索时保留尾随的空格。MySQL>创建表T1(C1 Char(10));查询OK,0行受影响(0.37秒)MySQL>插入T1(C1)值('XY');查询OK,1行受影响(0.01秒)MySQL> Set SQL_Mode ='';查询OK,0行受影响(0.00秒)MySQL>从T1中选择C1,Char_Length(C1);+ ------ + ---------------- + |C1 |char_length(c1)|+ ------ + ---------------- + |XY |2 | +------+-----------------+ 1 row in set (0.00 sec) mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT c1, CHAR_LENGTH(c1) FROM t1; +------------+-----------------+ | c1 | CHAR_LENGTH(c1) | +------------+-----------------+ | xy | 10 | +------------+-----------------+ 1 row in set (0.00 sec)
为所有存储引擎启用严格的SQL模式。拒绝无效的数据值。有关详细信息,请参阅
STRICT_ALL_TABLES
包括效果ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
模式。有关其他讨论,请参阅为事务性存储引擎启用严格的SQL模式,并在可能的情况下为非事务性存储引擎启用。有关详细信息,请参阅
STRICT_TRANS_TABLES
包括效果ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
模式。有关其他讨论,请参阅以下特殊模式是作为上一列表中模式值的组合的简写提供的。
相当于
REAL_AS_FLOAT
,PIPES_AS_CONCAT
,ANSI_QUOTES.
,Ignore_space.
,以及(从MySQL 5.7.5起)ONLY_FULL_GROUP_BY
。ANSI
模式还会导致服务器返回一个查询错误,其中设置了一个函数年代
使用外部引用
无法在外部查询中聚合,外部参考已解决。这是一个查询:年代
(外_ref.
)SELECT * FROM t1 WHERE t1。a IN (SELECT MAX(t1.b) FROM t2 WHERE…);
在这里,
马克斯(t1.b)
无法在外部查询中汇总,因为它出现在在哪里
这个问题的子句。在这种情况下,标准SQL会出现错误。如果ANSI
模式未启用,服务器处理
在这样的查询中,它将以同样的方式解释年代
(外_ref.
)
。年代
(常量
)相当于
PIPES_AS_CONCAT
,ANSI_QUOTES.
,Ignore_space.
,NO_KEY_OPTIONS
,NO_TABLE_OPTIONS
,NO_FIELD_OPTIONS
。笔记截至MySQL 5.7.22,
DB2
弃用。在MySQL 8.0中被删除。相当于
PIPES_AS_CONCAT
,ANSI_QUOTES.
,Ignore_space.
,NO_KEY_OPTIONS
,NO_TABLE_OPTIONS
,NO_FIELD_OPTIONS
,NO_AUTO_CREATE_USER
。笔记截至MySQL 5.7.22,
maxdb.
弃用。在MySQL 8.0中被删除。相当于
PIPES_AS_CONCAT
,ANSI_QUOTES.
,Ignore_space.
,NO_KEY_OPTIONS
,NO_TABLE_OPTIONS
,NO_FIELD_OPTIONS
。笔记截至MySQL 5.7.22,
该软件
弃用。在MySQL 8.0中被删除。相当于
MYSQL323
,HIGH_NOT_PRECEDENCE
。这意味着HIGH_NOT_PRECEDENCE
加一些显示创建表
特定的行为MYSQL323
:笔记截至MySQL 5.7.22,
MYSQL323
弃用。在MySQL 8.0中被删除。相当于
mysql40.
,HIGH_NOT_PRECEDENCE
。这意味着HIGH_NOT_PRECEDENCE
加上一些特定的行为mysql40.
。这些和for是一样的MYSQL323
,除了显示创建表
不显示堆
作为存储引擎内存
表。笔记截至MySQL 5.7.22,
mysql40.
弃用。在MySQL 8.0中被删除。相当于
PIPES_AS_CONCAT
,ANSI_QUOTES.
,Ignore_space.
,NO_KEY_OPTIONS
,NO_TABLE_OPTIONS
,NO_FIELD_OPTIONS
,NO_AUTO_CREATE_USER
。笔记截至MySQL 5.7.22,
甲骨文
弃用。在MySQL 8.0中被删除。相当于
PIPES_AS_CONCAT
,ANSI_QUOTES.
,Ignore_space.
,NO_KEY_OPTIONS
,NO_TABLE_OPTIONS
,NO_FIELD_OPTIONS
。笔记截至MySQL 5.7.22,
PostgreSQL.
弃用。在MySQL 8.0中被删除。在MySQL 5.7.4之前,以及在MySQL 5.7.8及以后版本中,
传统的
相当于STRICT_TRANS_TABLES
,STRICT_ALL_TABLES
,no_zero_in_date.
,NO_ZERO_DATE
,ERROR_FOR_DIVISION_BY_ZERO
,NO_AUTO_CREATE_USER
,no_engine_substitut
。来自MySQL 5.7.4虽然5.7.7,
传统的
相当于STRICT_TRANS_TABLES
,STRICT_ALL_TABLES
,NO_AUTO_CREATE_USER
,no_engine_substitut
。的no_zero_in_date.
,NO_ZERO_DATE
,ERROR_FOR_DIVISION_BY_ZERO
模式未命名,因为在这些版本中,它们的效果包含在严格的SQL模式的效果中(STRICT_ALL_TABLES
或STRICT_TRANS_TABLES
)。因此,影响传统的
在所有的MySQL 5.7版本中是相同的(和在MySQL 5.6中相同)。有关其他讨论,请参阅严格模式控制MySQL如何处理数据更改语句中无效或丢失的值,例如
插入
或更新
。有几个原因,值可能无效。例如,它可能具有列的错误数据类型,或者可能超出范围。当要插入的新行不包含非 - 的值时缺少值零
没有显式的列默认
条款的定义。(零
列,零
如果该值缺失,则插入。)严格模式还影响DDL语句,如创建表
。如果严格模式不生效,MySQL会为无效或丢失的值插入调整后的值,并产生警告(参见
插入忽略
或更新忽略
。对于诸如的陈述
选择
不更改数据的无效值在严格模式下生成警告,而不是错误。严格模式会产生一个错误,以便尝试创建超过最大键长度的键。当未启用严格模式时,这会导致键的警告和截断最大键长度。
严格模式不影响是否检查外键约束。
figner_key_checks.
可以使用它。(看STRICT_ALL_TABLES
或STRICT_TRANS_TABLES
启用,尽管这些模式的效果略有不同:对于事务表,在数据更改语句中的无效或缺失值时出现错误
STRICT_ALL_TABLES
或STRICT_TRANS_TABLES
启用。语句被终止并回滚。对于非事务性表,如果坏值出现在要插入或更新的第一行,则两种模式的行为都是相同的:终止语句,表保持不变。如果语句插入或修改了多行,坏值出现在第二行或之后的行,结果取决于启用了哪一种严格模式:
为
STRICT_ALL_TABLES
,MySQL返回错误并忽略其余行。但是,因为已插入或更新之前的行,结果是部分更新。为避免这种情况,请使用单行语句,无需更改表格中止。为
STRICT_TRANS_TABLES
, MySQL将一个无效值转换为最接近的有效值,并插入调整后的值。如果缺少一个值,MySQL将为列数据类型插入隐式的默认值。无论哪种情况,MySQL都会生成一个警告而不是一个错误并继续处理该语句。中描述了隐式缺省值严格模式影响处理除零,其中包括
国防部(
:N
, 0)如果未启用严格的模式,则按零插入划分
零
并没有产生警告。如果启用严格模式,除零会产生错误,除非
忽略
也给出了。为插入忽略
和更新忽略
,除以零插入零
并产生警告。
为
选择
,除以零返回零
。启用严格模式还会产生一个警告。严格模式影响服务器是否允许
“0000-00-00”
有效日期:如果没有启用严格模式,
“0000-00-00”
是允许的,插入不会产生警告。如果启用了严格的模式,
“0000-00-00”
是不允许的,插入会产生错误,除非忽略
也给出了。为插入忽略
和更新忽略
,“0000-00-00”
允许并插入发出警告。
严格模式影响服务器是否允许年份部分不为零但月或日部分为0的日期(例如
'2010-00-01'
或“2010-01-00”
):如果未启用严格的模式,则允许零部件的日期,插入不会产生警告。
如果启用了严格的模式,则不允许使用零部件的日期,并且缺口会产生错误,除非
忽略
也给出了。为插入忽略
和更新忽略
,零部分的日期插入为“0000-00-00”
(被认为有效忽略
),并发出警告。
有关严格模式的更多信息
忽略
,请参阅ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
模式。来自MySQL 5.7.4虽然5.7.7,ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
在明确命名时,模式不做任何事情,它们的效果都包含在严格模式的效果中。有关其他讨论,请参阅语句对语句执行的影响
忽略
关键字(将错误降级为警告)和严格SQL模式(将警告升级为错误)。它描述了它们影响哪些语句,以及它们适用于哪些错误。下表给出了在默认情况下产生错误和警告时语句行为的摘要比较。在默认情况下会产生错误的一个例子是插入
零
进入A.没有空
列。在默认情况下产生警告的一个例子是在列中插入错误数据类型的值(例如插入字符串)“abc”
转换为整数列)。运作模式 当“Statement Default”为“Error”时 当语句默认为警告时 没有 忽略
或严格SQL模式错误 警告 与 忽略
警告 警告(与没有相同 忽略
或严格的SQL模式)使用严格的SQL模式 错误(与无相同 忽略
或严格的SQL模式)错误 与 忽略
和严格SQL模式警告 警告 从表格中可以得出的一个结论是当
忽略
关键字和严格SQL模式都是有效的,忽略
优先。这意味着,尽管忽略
和严格的SQL模式可以被认为对错误处理有相反的影响,当它们一起使用时不会取消。MySQL中的几个语句支持可选
忽略
关键词。此关键字使服务器降级某些类型的错误并改为生成警告。对于多行陈述,忽略
使语句跳到下一行而不是中止。(对于不可忽略的错误,无论忽略
关键词。)示例:如果表格
t
有一个主键列我
的值,试图插入相同的值我
进入多行通常会产生一个重复键错误:mysql> INSERT INTO t (i) VALUES(1),(1);ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
与
忽略
,包含重复键的行仍然没有插入,但是会出现警告而不是错误:MySQL>插入忽略进入T(i)值(1),(1);查询OK,1行受影响,1条警告(0.01秒)记录:2重复项:1警告:1 MySQL>显示警告;+ --------- + ------ + ----------------------------------------------- + |水平|代码|消息|+ --------- + ------ + ----------------------------------------------- + |警告|1062 |密钥“初级”的重复条目'1'| +---------+------+---------------------------------------+ 1 row in set (0.00 sec)
这些语句支持
忽略
关键字:的
忽略
关键字适用于以下可忽略的错误:er_bad_null_dup_entry_with_key_name er_dup_key er_no_partition_for_given_value er_no_partition_for_given_value_silent er_no_does_not_match_given_partition_set er_row_is_referenced_2 er_subquery_no_1_row er_view_check_failed
严格SQL模式对语句执行的影响
MySQL Server可以以不同的SQL模式运行,并且可以针对不同的客户端以不同的方式应用这些模式,具体取决于该模式
sql_mode.
系统变量。在”严格的”SQL模式下,服务器将某些警告升级为错误。例如,在非严格SQL模式下,插入字符串
“abc”
将值转换为0并发出警告:mysql> SET sql_mode = ";mysql> INSERT INTO t (i) VALUES('abc');mysql> SHOW WARNINGS(警告)+---------+------+--------------------------------------------------------+ | 水平| |消息代码 | +---------+------+--------------------------------------------------------+ | 警告| 1366 |不正确的整数值:“abc”列在第一行“我” | +---------+------+--------------------------------------------------------+ 1行集(0.00秒)
在严格的SQL模式下,错误的值拒绝错误:
mysql> SET sql_mode = 'STRICT_ALL_TABLES';mysql> INSERT INTO t (i) VALUES('abc');ERROR 1366 (HY000):不正确的整数值:'abc'为列'i'在行1
的可能设置的详细信息
sql_mode.
系统变量,见
在存储程序中,如果程序是在严格模式下定义的,那么刚才列出的类型的单个语句将以严格SQL模式执行。
严格SQL模式适用于以下错误,它们表示输入值无效或缺失的一类错误。如果值的列数据类型错误或超出范围,则该值无效。如果要插入的新行不包含
没有空
没有显式的列默认
条款的定义。ER_BAD_NULL_ERROR ER_CUT_VALUE_GROUP_CONCAT ER_DATA_TOO_LONG ER_DATETIME_FUNCTION_OVERFLOW ER_DIVISION_BY_ZERO ER_INVALID_ARGUMENT_FOR_LOGARITHM ER_NO_DEFAULT_FOR_FIELD ER_NO_DEFAULT_FOR_VIEW_FIELD ER_TOO_LONG_KEY ER_TRUNCATED_WRONG_VALUE ER_TRUNCATED_WRONG_VALUE_FOR_FIELD ER_WARN_DATA_OUT_OF_RANGE ER_WARN_NULL_TO_NOTNULL ER_WARN_TOO_FEW_RECORDSER_WRONG_ARGUMENTS ER_WRONG_VALUE_FOR_TYPE WARN_DATA_TRUNCATED
笔记因为持续的MySQL开发定义了新的错误,可能会有前面列表中没有严格的SQL模式适用的错误。
在MySQL 5.7.22中,已弃用这些SQL模式,并在MySQL 8.0中删除:
DB2
,maxdb.
,该软件
,MYSQL323
,mysql40.
,甲骨文
,PostgreSQL.
,NO_FIELD_OPTIONS
,NO_KEY_OPTIONS
,NO_TABLE_OPTIONS
。在MySQL 5.7中
ONLY_FULL_GROUP_BY
SQL模式默认启用,因为集团
处理已经变得更加复杂,包括功能依赖项的检测。但是,如果你发现ONLY_FULL_GROUP_BY
启用会导致对现有应用程序的查询被拒绝,这些操作中的任何一个都应该恢复操作:如果可以修改有问题的查询,那么就这样做,这样可以使非聚合列在功能上依赖
集团
列,或引用非聚合列Any_Value()
。如果不可能修改有问题的查询(例如,如果它是由第三方应用程序生成的),则设置
sql_mode.
系统变量在服务器启动时不启用ONLY_FULL_GROUP_BY
。
在MySQL 5.7中
ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
不赞成使用SQL模式。长期的计划是将这三种模式包含在严格的SQL模式中,并在MySQL的未来版本中将它们作为显式模式删除。为了兼容MySQL 5.7和MySQL 5.6的严格模式,并为受影响的应用程序修改提供额外的时间,以下行为适用:ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
不是严格SQL模式的一部分,但它的目的是与严格模式一起使用。作为提醒,如果启用了它们而没有启用严格模式(反之亦然),则会出现警告。ERROR_FOR_DIVISION_BY_ZERO
,NO_ZERO_DATE
,no_zero_in_date.
默认启用。
通过上述更改,默认情况下仍然启用了更严格的数据检查,但在当前需要或需要禁用的环境中,可以禁用各个模式。