【问题标题】:h2 does not enforce NOT NULL in MySQL compatibility modeh2 在 MySQL 兼容模式下不强制执行 NOT NULL
【发布时间】:2013-11-29 13:24:53
【问题描述】:

在MySQL兼容模式下,以下SQL成功,返回0:

CREATE TABLE test2 (i INTEGER NOT NULL);
INSERT INTO test2 VALUES (NULL);
SELECT * FROM test2;

它在默认模式下按预期失败。 MySQL 5.5 / InnoDB 也失败了。 “MySQL 兼容性”实际上是指“MyISAM 兼容性”吗?

【问题讨论】:

  • 如果你使用INSERT INTO test2 VALUES (NULL), (NULL);,MySQL会很乐意插入0——至少在默认的sql_mode中是这样。我想我也看到它插入了 0 和一个单值插入,但我不记得确切的情况了。

标签: h2


【解决方案1】:

这个问题是由于MySQL 处理Null 值的方式和h2 造成的。基本上MySQL 将收到的空值转换为empty string/0,而h2 则在所有三种类型之间有明显的区别。

因此,他们(h2)决定在MYSQL 模式下将空值转换为 0/空字符串/当前时间戳。但是由于 as per core h2 0/empty 字符串不是空字符串,所以它插入了数据。

使用org.h2.engine.Mode并修改与此相关的变量:

Mode mode = Mode.getInstance("MYSQL");
mode.convertInsertNullToZero = false;

这对我有用。感谢this 链接。

【讨论】:

  • 你知道如何在 spring/maven xml 中做到这一点吗?我找不到任何文档表明:\
【解决方案2】:

来自H2: MySQL Compatibility Mode

在插入数据时,如果一列定义为 NOT NULL 并插入 NULL,则使用 0(或空字符串,或时间戳列的当前时间戳)值。 通常,不允许该操作,并抛出异常。

MySQL 手册中关于 INSERT 的内容如下,没有区分 MyISAM 或 InnoDB:

将 NULL 插入已声明为 NOT NULL 的列中。对于多行 INSERT 语句 [..],列设置为列数据类型的隐式默认值。 [..](对于单行 INSERT,当 NULL 插入 NOT NULL 列时不会出现警告。相反,语句会失败并出现错误。

因此,我不确定 H2 为何或从何处做出此选择。

【讨论】:

  • 糟糕。我想除了 H2 文档外,我到处都看过。 :-) 我喜欢 MySQL 行为的变化,具体取决于您插入的行数。我认为我最好的选择是将来使用默认模式。感谢您的帮助!
猜你喜欢
  • 2017-05-08
  • 2017-09-27
  • 1970-01-01
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
  • 2019-11-04
  • 2012-09-10
  • 1970-01-01
相关资源
最近更新 更多