Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


7.1.11 服务器 SQL 模式

MySQL 服务器可以在不同的 SQL 模式下运行,并且可以根据sql_mode系统变量的值对不同的客户端应用不同的模态。DBA 可以将全局 SQL 模式设置为与站点服务器操作要求相匹配,每个应用程序可以将其会话 SQL 模式设置为其自己的要求。

模态影响 MySQL 支持的 SQL 语法和数据验证检查。这使得在不同的环境中使用 MySQL 并与其他数据库服务器一起使用更加容易。

对于 MySQL 服务器 SQL 模式的问题,请查看第 A.3 节,“MySQL 8.4 FAQ: 服务器 SQL 模式”

在使用InnoDB表时,请考虑innodb_strict_mode系统变量。它启用了InnoDB表的额外错误检查。

MySQL 8.4 的默认 SQL 模式包括以下模式:ONLY_FULL_GROUP_BYSTRICT_TRANS_TABLESNO_ZERO_IN_DATENO_ZERO_DATEERROR_FOR_DIVISION_BY_ZERONO_ENGINE_SUBSTITUTION

在服务器启动时,使用命令行选项--sql-mode=<modes>或在选项文件,如my.cnf(Unix操作系统)或my.ini(Windows),将SQL模式设置为modes,其中modes是以逗号分隔的多个模式。要清除SQL模式,设置为空字符串使用--sql-mode=""命令行选项或sql-mode=""选项文件。

Note

MySQL安装程序可能在安装过程中配置SQL模式。

如果SQL模式与默认值或您期望的值不同,请检查服务器读取的选项文件中是否存在设置。

要在运行时更改SQL模式,使用SET语句将全局或会话sql_mode系统变量设置:

SET GLOBAL sql_mode = 'modes';
SET SESSION sql_mode = 'modes';

设置GLOBAL变量需要SYSTEM_VARIABLES_ADMIN权限(或弃用的SUPER权限),对所有连接的客户端产生影响。设置SESSION变量只对当前客户端产生影响,每个客户端都可以在任何时候更改其会话sql_mode值。

要确定当前全局或会话sql_mode设置,请选择其值:

SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode;
Important

SQL模式和自定义分区。更改服务器SQL模式后创建和插入数据到分区表中可能会导致这些表的行为发生major变化,并可能导致数据丢失或损坏。强烈建议您从未更改使用自定义分区的表的SQL模式。

在复制分区表时,源服务器和副本服务器上的SQL模式不同也可能导致问题。为了获得最佳结果,请始终在源服务器和副本服务器上使用相同的服务器SQL模式。

更多信息,请见第26.6节,“分区限制和限制”

最重要的sql_mode值可能是:

  • ANSI

    该模式将语法和行为调整为更紧密地遵循标准SQL。它是组合模式列表的其中一个,位于本节末尾。

  • STRICT_TRANS_TABLES

    如果不能将值插入事务表中,就中止语句。如果是非事务表,就在单行语句或多行语句的第一行中止语句。更多详细信息请见本节后面。

  • TRADITIONAL

    使MySQL像传统的SQL数据库系统一样。该模式的简单描述是“插入错误值时给出错误,而不是警告”。它是组合模式列表的其中一个,位于本节末尾。

    Note

    在启用TRADITIONAL模式时,INSERTUPDATE语句将在错误发生时中止。如果您使用非事务存储引擎,这可能不是您想要的,因为在错误发生前已经执行的数据更改可能不会被回滚,从而导致部分完成的更新。

当本手册提到“严格模式”时,它指的是启用了STRICT_TRANS_TABLESSTRICT_ALL_TABLES其中一种或两种模式。

以下是所有支持的SQL模式的列表:

  • ALLOW_INVALID_DATES

    不执行完整的日期检查。只检查月份是否在1-12范围内,日期是否在1-31范围内。这可能对Web应用程序有用,该应用程序从用户处获取年、月、日三个字段,并将用户输入的值存储在数据库中,而不进行日期验证。这一模式适用于DATEDATETIME列,不适用于TIMESTAMP列,因为TIMESTAMP列总是需要有效的日期。

    ALLOW_INVALID_DATES禁用时,服务器要求月份和日期值是合法的,而不是仅在1到12和1到31范围内。禁用严格模式时,非法日期,如'2004-04-31',将被转换为'0000-00-00',并生成警告。启用严格模式时,非法日期将生成错误。要允许这些日期,启用ALLOW_INVALID_DATES

  • ANSI_QUOTES

    "视为标识符引号字符(类似于`引号字符),而不是字符串引号字符。您仍然可以使用`来引用标识符,以便启用该模式。启用ANSI_QUOTES时,您不能使用双引号来引用文字字符串,因为它们将被解释为标识符。

  • ERROR_FOR_DIVISION_BY_ZERO

    ERROR_FOR_DIVISION_BY_ZERO模式影响零除操作,包括MOD(N,0)。对于数据更改操作(INSERTUPDATE),其效果还取决于是否启用严格SQL模式。

    • 如果该模式未启用,零除操作将插入NULL,并生成警告。

    • 如果该模式启用,零除操作将插入NULL,并生成警告。

    • 如果该模式和严格模式都启用,零除操作将生成错误,除非给出IGNORE。对于INSERT IGNOREUPDATE IGNORE,零除操作将插入NULL,并生成警告。

    对于SELECT,零除操作将返回NULL。启用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模式的效果中。

  • 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_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
  • IGNORE_SPACE

    允许在函数名称和(字符之间添加空格。这使得内置函数名称被视为保留字。因此,同名的标识符必须像第11.2节,“Schema Object Names”中所述那样被引用。例如,因为存在COUNT()函数,因此使用count作为表名的以下语句将导致错误:

    mysql> CREATE TABLE count (i INT);
    ERROR 1064 (42000): You have an error in your SQL syntax

    表名应该被引用:

    mysql> CREATE TABLE `count` (i INT);
    Query OK, 0 rows affected (0.00 sec)

    IGNORE_SPACE SQL模式仅适用于内置函数,而不是可加载函数或存储函数。总是可以在可加载函数或存储函数名称后添加空格,无论是否启用IGNORE_SPACE

    关于IGNORE_SPACE的进一步讨论,请见第11.2.5节,“Function Name Parsing and Resolution”

  • NO_AUTO_VALUE_ON_ZERO

    NO_AUTO_VALUE_ON_ZERO影响AUTO_INCREMENT列的处理。通常,您可以通过将AUTO_INCREMENT列插入0NULL来生成下一个顺序号。NO_AUTO_VALUE_ON_ZERO将抑制0的这种行为,使得只有NULL生成下一个顺序号。

    这个模式可以在将0存储在表的AUTO_INCREMENT列中时非常有用。存储0并不是推荐的实践方法。例如,如果使用mysqldump将表dump到文件,然后重新加载该文件,MySQL通常会在遇到0值时生成新的序列号,从而导致dump的表内容不同于原始表。启用NO_AUTO_VALUE_ON_ZERO在重新加载dump文件时解决这个问题。因此,mysqldump自动在输出中包含启用NO_AUTO_VALUE_ON_ZERO的语句。

  • NO_BACKSLASH_ESCAPES

    启用这个模式将禁用在字符串和标识符中使用反斜杠字符(\)作为转义字符。启用该模式时,反斜杠将变为任何其他字符一样,并且LIKE表达式的默认转义序列将被更改为不使用转义字符。

  • NO_DIR_IN_CREATE

    在创建表时,忽略所有INDEX DIRECTORYDATA DIRECTORY指令。这项选项在复制服务器上非常有用。

  • NO_ENGINE_SUBSTITUTION

    控制在语句,如CREATE TABLEALTER TABLE指定的存储引擎是禁用或未编译的时自动替换默认存储引擎。

    默认情况下,NO_ENGINE_SUBSTITUTION是启用的。

    由于存储引擎可以在运行时插件,因此 unavailable引擎将被视为同样处理:

    CREATE TABLE中,使用默认引擎,并在无法使用所需引擎时出现警告。在ALTER TABLE中,出现警告并且表不会被修改。

    在启用NO_ENGINE_SUBSTITUTION时,出现错误并且表不会被创建或修改如果无法使用所需引擎。

  • NO_UNSIGNED_SUBTRACTION

    在整数值之间进行减法操作,其中一个是类型为UNSIGNED的,结果默认为无符号结果。如果结果将否则为负,错误结果:

    mysql> SET sql_mode = '';
    Query OK, 0 rows affected (0.00 sec)
    
    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;
    +-------------------------+
    | CAST(0 AS UNSIGNED) - 1 |
    +-------------------------+
    |                      -1 |
    +-------------------------+

    如果结果的结果用于更新一个UNSIGNED整数列,结果将被截断到该列类型的最大值,或者在启用NO_UNSIGNED_SUBTRACTION的情况下截断到0。如果启用严格 SQL 模式,错误将发生,列将保持不变。

    NO_UNSIGNED_SUBTRACTION启用时,减法结果将是有符号的,即使任何操作数是无符号的。例如,比较表t1中的列c2和表t2中的列c2

    mysql> SET sql_mode='';
    mysql> CREATE TABLE test (c1 BIGINT UNSIGNED NOT NULL);
    mysql> CREATE TABLE t1 SELECT c1 - 1 AS c2 FROM test;
    mysql> DESCRIBE t1;
    +-------+---------------------+------+-----+---------+-------+
    | Field | Type                | Null | Key | Default | 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在所有上下文中不可完全使用。请参阅第14.10节,“Cast Functions and Operators”

  • NO_ZERO_DATE

    模式NO_ZERO_DATE影响服务器是否允许'0000-00-00'作为有效日期。其效果还取决于是否启用严格 SQL 模式。

    • 如果不启用该模式,'0000-00-00'将被允许,插入操作将不产生警告。

    • 如果启用该模式,'0000-00-00'将被允许,插入操作将产生警告。

    • 如果启用该模式和严格模式,'0000-00-00'将不被允许,插入操作将产生错误,除非使用IGNORE。对于INSERT IGNOREUPDATE IGNORE'0000-00-00'将被允许,插入操作将产生警告。

    NO_ZERO_DATE已弃用。NO_ZERO_DATE不属于严格模式的一部分,但应该与严格模式一起使用,并且默认启用。警告将出现,如果启用NO_ZERO_DATE而不启用严格模式或 vice versa。

    由于NO_ZERO_DATE已弃用,您应该期望它在未来 MySQL 发布中被删除,并且其效果包含在严格 SQL 模式的效果中。

  • NO_ZERO_IN_DATE

    NO_ZERO_IN_DATE》模式影响服务器是否允许年份部分为零,但月份或日期部分为零的日期(例如:'2010-00-01''2010-01-00'),但不允许'0000-00-00'。要控制服务器是否允许'0000-00-00',请使用NO_ZERO_DATE模式。《NO_ZERO_IN_DATE》的效果还取决于是否启用严格SQL模式。

    • 如果不启用这个模式,零部分日期允许,并且插入操作不产生警告。

    • 如果启用这个模式,零部分日期将被插入为'0000-00-00',并产生警告。

    • 如果启用这个模式和严格模式,零部分日期将不被允许,并且插入操作产生错误,除非使用IGNORE。对于INSERT IGNOREUPDATE IGNORE,零部分日期将被插入为'0000-00-00',并产生警告。

    NO_ZERO_IN_DATE已弃用。《NO_ZERO_IN_DATE》不属于严格模式,但应该与严格模式一起使用,并且默认启用。启用《NO_ZERO_IN_DATE》而不启用严格模式或反之将产生警告。

    由于《NO_ZERO_IN_DATE》已弃用,您应该期望在未来MySQL版本中将其作为单独的模式名称删除,并将其效果包含在严格SQL模式中。

  • ONLY_FULL_GROUP_BY

    拒绝查询,其中选择列表、HAVING子句或ORDER BY列表引用非聚合列,但这些列既不在GROUP BY子句中命名,也不函数依赖于GROUP BY列。

    MySQL扩展了标准SQL,允许HAVING子句引用别名表达式在选择列表中。无论是否启用ONLY_FULL_GROUP_BY,HAVING子句都可以引用别名。

    对于更多讨论和示例,请见第14.19.3节,“MySQL Handling of GROUP BY”

  • PAD_CHAR_TO_FULL_LENGTH

    默认情况下,在检索CHAR列值时,尾部空格将被去除。如果启用了PAD_CHAR_TO_FULL_LENGTH,则不会去除尾部空格,并将检索到的CHAR值填充到其完整长度。这一模式不适用于VARCHAR列,因为在检索时尾部空格将被保留。

    Note

    PAD_CHAR_TO_FULL_LENGTH已弃用。预计将在未来的MySQL版本中删除。

    mysql> CREATE TABLE t1 (c1 CHAR(10));
    Query OK, 0 rows affected (0.37 sec)
    
    mysql> INSERT INTO t1 (c1) VALUES('xy');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> SET sql_mode = '';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> SELECT c1, CHAR_LENGTH(c1) FROM t1;
    +------+-----------------+
    | 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)
  • PIPES_AS_CONCAT

    ||视为字符串连接操作符(与CONCAT()相同),而不是OR的同义词。

  • REAL_AS_FLOAT

    REAL视为FLOAT的同义词。默认情况下,MySQL将REAL视为DOUBLE的同义词。

  • STRICT_ALL_TABLES

    为所有存储引擎启用严格SQL模式。无效数据值将被拒绝。详见严格SQL模式

  • STRICT_TRANS_TABLES

    为事务存储引擎启用严格SQL模式,并且在可能的情况下为非事务存储引擎启用。详见严格SQL模式

  • TIME_TRUNCATE_FRACTIONAL

    控制在插入TIMEDATETIMESTAMP值的fractional seconds 部分到具有相同类型但更少fractional digits 的列时是否进行舍入或截断。默认行为是使用舍入。如果启用了该模式,截断将发生。以下是一系列语句,展示了不同情况的结果:

    CREATE TABLE t (id INT, tval TIME(1));
    SET sql_mode='';
    INSERT INTO t (id, tval) VALUES(1, 1.55);
    SET sql_mode='TIME_TRUNCATE_FRACTIONAL';
    INSERT INTO t (id, tval) VALUES(2, 1.55);

    结果表的内容如下,第一个值被舍入,第二个值被截断:

    mysql> SELECT id, tval FROM t ORDER BY id;
    +------+------------+
    | id   | tval       |
    +------+------------+
    |    1 | 00:00:01.6 |
    |    2 | 00:00:01.5 |
    +------+------------+

    请参见第13.2.6节,“时间值中的fractional seconds”

以下是一些特殊模式,用于简化之前列表中的组合模式。

严格模式控制 MySQL 如何处理无效或缺失的数据更改语句,如INSERTUPDATE。一个值可能无效的原因有多种。例如,它可能具有错误的数据类型或超出范围。一个值是缺失的,当一个新行要被插入时,但该行中没有为非空列指定的值,该列没有明确的默认值定义。 (对于一个空列,MySQL 将插入 NULL 值。) 严格模式也影响DDL 语句,如CREATE TABLE

如果严格模式不在 effect 中,MySQL 将插入调整后的值以处理无效或缺失的值,并生成警告(见Section 15.7.7.41, “SHOW WARNINGS 语句”)。在严格模式下,您可以使用INSERT IGNOREUPDATE IGNORE

对于不改变数据的语句,如SELECT,严格模式下无效值将生成警告,而不是错误。

严格模式将产生错误,以尝试创建的键超过最大键长度。当严格模式不在 effect 中,这将生成警告,并将键截断到最大键长度。

严格模式不影响外键约束的检查。foreign_key_checks 可以用于该目的。 (见Section 7.1.8, “Server System Variables”。)

严格 SQL 模式在 effect 中,如果启用了STRICT_ALL_TABLESSTRICT_TRANS_TABLES,尽管这两个模式的效果有所不同:

  • 对于事务表,启用STRICT_ALL_TABLESSTRICT_TRANS_TABLES时,出现无效或缺失值的数据更改语句将引发错误。语句将被中止并回滚。

  • 对于非事务表,如果在插入或更新的第一行出现错误值,语句将被中止,表格保持不变。如果语句插入或修改多行,并且错误值出现在第二行或更后行,结果取决于启用的严格模式:

    • 对于STRICT_ALL_TABLES,MySQL返回错误并忽略剩余的行。然而,因为早期行已经被插入或更新,结果是一个部分更新。为了避免这种情况,使用单行语句,这些语句可以在不改变表格的情况下被中止。

    • 对于STRICT_TRANS_TABLES,MySQL将无效值转换为最接近的有效值,并插入调整后的值。如果值缺失,MySQL将插入该列的隐式默认值。在任何情况下,MySQL都会生成警告,而不是错误。隐式默认值在第13.6节,“Data Type Default Values”中有描述。

严格模式对零除法、零日期和零日期的处理方式如下:

  • 严格模式对零除法的处理包括MOD(N,0)

    对于数据更改操作(INSERTUPDATE):

    • 如果严格模式未启用,零除法将插入NULL并产生无警告。

    • 如果严格模式启用,零除法将产生错误,除非同时启用IGNORE。对于INSERT IGNOREUPDATE IGNORE,零除法将插入NULL并产生警告。

    对于SELECT,零除法将返回NULL。启用严格模式将生成警告。

  • 严格模式对是否允许'0000-00-00'作为有效日期的处理方式如下:

    • 如果严格模式未启用,'0000-00-00'将被允许,并且插入语句将产生无警告。

    • 如果严格模式启用,'0000-00-00'将不被允许,并且插入语句将产生错误,除非同时启用IGNORE。对于INSERT IGNOREUPDATE IGNORE'0000-00-00'将被允许,并且插入语句将产生警告。

  • 严格模式对是否允许日期的处理方式如下:

    • 如果严格模式未启用,零部分日期允许,并且插入操作不产生警告。

    • 如果严格模式启用,零部分日期不允许,并且插入操作产生错误,除非同时使用IGNORE。对于INSERT IGNOREUPDATE IGNORE,零部分日期将被插入为'0000-00-00'(被认为是有效的),并且产生警告。

有关IGNORE和严格 SQL 模式的更多信息,请参见IGNORE 关键字和严格 SQL 模式的比较

严格模式对零除法、零日期和零日期组件的处理方式受影响,包括ERROR_FOR_DIVISION_BY_ZERONO_ZERO_DATENO_ZERO_IN_DATE模式。

本节比较了IGNORE关键字(将错误降级为警告)和严格 SQL 模式(将警告升级为错误)的语句执行效果。它描述了哪些语句受影响,以及哪些错误被应用。

以下表格总结了语句行为的比较,当默认情况下产生错误或警告。例如,当默认情况下产生错误时,插入一个NULL值到NOT NULL列中。例如,当默认情况下产生警告时,插入错误的数据类型到列中(例如,将字符串'abc'插入到整数列中)。

Operational Mode When Statement Default is Error When Statement Default is Warning
Without IGNORE or strict SQL mode 错误 警告
With IGNORE 警告 警告(与否使用IGNORE或严格 SQL 模式相同)
With strict SQL mode 错误(与否使用IGNORE或严格 SQL 模式相同) 错误
With IGNORE and strict SQL mode 警告 警告

从表格中可以得出结论,即当IGNORE关键字和严格 SQL 模式同时使用时,IGNORE优先。因此,虽然IGNORE和严格 SQL 模式可以被认为是相反的错误处理方式,但它们在一起使用时不互相取消。

MySQL 支持多个语句,其中包括可选的IGNORE关键字。这个关键字使服务器将某些类型的错误降级为警告。对于多行语句,降低错误到警告可能使行被处理。否则,IGNORE将语句跳到下一行,而不是中止。 (对于不可忽略的错误,错误仍然会发生, REGARDLESS OF THE IGNORE 关键字。)

示例:如果表t具有唯一值的主键列i,尝试将i的相同值插入多行通常会产生重复键错误:

mysql> CREATE TABLE t (i INT NOT NULL PRIMARY KEY);
mysql> INSERT INTO t (i) VALUES(1),(1);
ERROR 1062 (23000): Duplicate entry '1' for key 't.PRIMARY'

使用IGNORE,仍然不会插入重复键的行,但会出现警告而不是错误:

mysql> INSERT IGNORE INTO t (i) VALUES(1),(1);
Query OK, 1 row affected, 1 warning (0.01 sec)
Records: 2  Duplicates: 1  Warnings: 1

mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1062 | Duplicate entry '1' for key 't.PRIMARY' |
+---------+------+-----------------------------------------+
1 row in set (0.00 sec)

示例:如果表t2具有NOT NULLid,尝试插入NULL将在严格SQL模式下产生错误:

mysql> CREATE TABLE t2 (id INT NOT NULL);
mysql> INSERT INTO t2 (id) VALUES(1),(NULL),(3);
ERROR 1048 (23000): Column 'id' cannot be null
mysql> SELECT * FROM t2;
Empty set (0.00 sec)

如果SQL模式不是严格的,IGNORE将将NULL插入到列的隐式默认值(在这个例子中是0),从而使得行可以被处理而不被跳过:

mysql> INSERT INTO t2 (id) VALUES(1),(NULL),(3);
mysql> SELECT * FROM t2;
+----+
| id |
+----+
|  1 |
|  0 |
|  3 |
+----+

这些语句支持IGNORE关键字:

  • CREATE TABLE ... SELECTIGNORE不适用于CREATE TABLESELECT语句的部分,而是对插入到由SELECT产生的行的表中行的插入。重复的行将被忽略。

  • DELETEIGNORE将忽略删除过程中的错误。

  • INSERT:使用IGNORE,重复的行将被忽略。将要导致数据转换错误的行将被设置为最近的有效值。

    对于分区表,如果找不到匹配给定值的分区,IGNORE将导致插入操作失败。

  • LOAD DATALOAD XML:使用IGNORE,重复的行将被忽略。

  • UPDATE:使用IGNORE,重复键冲突的行将不被更新。将要导致数据转换错误的行将被设置为最近的有效值。

IGNORE关键字适用于以下忽略错误:

MySQL 服务器可以在不同的 SQL 模式下运行,并且可以根据 sql_mode 系统变量的值,对不同客户端应用不同的模式。

例如,在非严格 SQL 模式下,将字符串 'abc' 插入到整数列中将会将值转换为 0,并显示警告:

mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t (i) VALUES('abc');
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------------------+
| Level   | Code | Message                                                |
+---------+------+--------------------------------------------------------+
| Warning | 1366 | Incorrect integer value: 'abc' for column 'i' at row 1 |
+---------+------+--------------------------------------------------------+
1 row in set (0.00 sec)

在严格 SQL 模式下,非法值将被拒绝,并显示错误:

mysql> SET sql_mode = 'STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t (i) VALUES('abc');
ERROR 1366 (HY000): Incorrect integer value: 'abc' for column 'i' at row 1

关于 sql_mode 系统变量的可能设置,请参见 第7.1.11节,“Server SQL Modes”

严格 SQL 模式适用于以下语句,在某些情况下可能会超出范围或插入无效行到或从表中删除:

在存储程序中,单个语句(如上所列)将在严格 SQL 模式下执行,如果该程序是在严格模式下定义的。

严格 SQL 模式适用于以下错误,这些错误表示输入值无效或缺失。值无效如果其数据类型与列不符或超出范围。值缺失如果要插入的新行不包含对NOT NULL列(没有明确DEFAULT子句)的值。

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_RECORDS
ER_WRONG_ARGUMENTS
ER_WRONG_VALUE_FOR_TYPE
WARN_DATA_TRUNCATED
Note

由于继续 MySQL 发展定义了新的错误,因此可能有错误不在前面列表中,适用于严格 SQL 模式。