代码之家  ›  专栏  ›  技术社区  ›  Atul

字段值无效的INSERT IGNORE实际插入零

  •  0
  • Atul  · 技术社区  · 9 年前

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

    如果我运行查询 INSERT IGNORE 具有 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 回复  |  直到 9 年前
        1
  •  2
  •   Community CDub    5 年前

    我想你误解了什么 IGNORE 正在忽略。它不进行值检查和忽略错误值,它只是忽略或处理试图插入这些错误值所导致的错误。 From the manual :

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

    数值列的“最接近值” is zero :

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

    如果尝试将NULL存储到不接受NULL值的列中,MySQL Server将为列数据类型存储隐式默认值。通常,数值类型为0

    如在另一个答案中提到的, setting the mode to strict 将阻止这种行为。您可以在运行时使用以下查询在会话中设置:

    SET SESSION sql_mode = 'STRICT_ALL_TABLES';
    

    要在服务器范围内做到这一点,请使用 --sql-mode="STRICT_ALL_TABLES" 或添加 sql-mode="STRICT_ALL_TABLES" 给你的 my.cnf 配置文件。

        2
  •  1
  •   Ben Link    9 年前

    您应该指定:

    设置sql_mode=“strict_all_tables”;

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