带有无效字段值的INSERT IGNORE实际上插入了零

时间:2016-01-20 17:36:52

标签: mysql

我在我的表格中定义了一个NOT NULL字段。

如果我使用INSERT IGNORE运行查询null,则会插入一个零值的行,而不是忽略null值。 (即使对于具有无效数据类型的值,也会发生相同的情况)

CREATE TABLE all_numbers (
    Numbers INT NOT NULL,
    AssociatedNumbers INT NOT NULL
) ENGINE=InnoDB;

INSERT IGNORE INTO all_numbers (Numbers, AssociatedNumbers)
    VALUES (1,2), (3,4), (5,6), (7,8), (null, null);

输出是:

Numbers AssociatedNumbers
   1          2
   3          4
   5          6
   7          8
   0          0

同样的情况:

INSERT IGNORE INTO all_numbers (Numbers, AssociatedNumbers)
    VALUES (1,2), (3,4), (5,6), (7,8), ('a', 'b');

知道为什么会发生这种情况,以及如何让MySQL只是忽略在查询中指定的无效值? (零而不是无效值是非常不受欢迎的!)

更新

即使我启用了STRICT_ALL_TABLES模式,它仍然无效。以下是截图:

Output of <code>SELECT @@GLOBAL.sql_mode;</code>

INSERT query output

2 个答案:

答案 0 :(得分:1)

您应该指定:

设置sql_mode =“strict_all_tables”;

这将使检查更严格并给出正确的结果。

答案 1 :(得分:1)

我认为你误解了IGNORE忽略了什么。它不进行值检查并忽略错误值,它只是忽略或解决因尝试插入这些错误值而导致的错误。 From the manual

  

如果未指定IGNORE,则会触发错误的数据转换会中止语句。使用IGNORE,将无效值调整为最接近的值并插入;产生警告,但声明不会中止。您可以使用mysql_info()C API函数确定实际在表中插入了多少行。

&#34;最接近的值&#34;对于数字列is zero

  

如果您尝试将不以数字开头的字符串存储到数字列中,MySQL Server将存储0。

     

...

     

如果您尝试将NULL存储到不会取值的列中...... MySQL Server会存储列数据类型的隐式默认值。通常,对于数字类型,这是0 ...

如另一个答案所述,setting the mode to strict会阻止此行为。您可以在运行时使用此查询在会话中设置此项:

SET SESSION sql_mode = 'STRICT_ALL_TABLES';

要在服务器范围内执行此操作,请使用--sql-mode="STRICT_ALL_TABLES"启动MySQL或将sql-mode="STRICT_ALL_TABLES"添加到my.cnf配置文件中。