22

当 MySQL 允许我将 aNULL插入使用NOT NULL. 我做了一些研究,发现了如何启用严格模式。但是,我不太确定STRICT_ALL_TABLES启用 MySQL 时会执行什么验证。

手册说:

严格模式控制 MySQL 如何处理无效或丢失的输入值。一个值可能由于多种原因而无效。(强调我的)例如,它可能具有错误的列数据类型,或者它可能超出范围。

我了解它认为缺少什么以及如何处理它。我不清楚它认为什么无效。我做了一些测试并发现了以下内容:

  • 太长的字符串无效
  • 超出范围的数字无效
  • NULLNULL列的 s 无效
  • TRUE并且FALSE似乎总是有效的(它们分别变为 1 和 0)
  • 无效日期无效
  • 零日期有效(可以启用其他模式来更改此行为)
  • 整数字段中的浮点数是有效的(它们被四舍五入)
  • 数字字段中的字母无效

除了上面提到的之外,MySQL 是否进行任何其他验证检查?

手册说“列的数据类型错误”,但我看到的唯一实际发挥作用的情况是数字字段中的字母。还有其他数据类型错误的例子吗?

是否有一个关于 MySQL 执行的检查的列表?

编辑:作为记录,我的应用程序已经进行了广泛的验证。我使用严格模式作为最后的机会,以防万一。如果我忘记检查某些内容,我希望它快速失败,而不是“默默地破坏我的数据”。

4

2 回答 2

9

一个很好的资源是检查 MySQL 源代码,并阅读mysql-test/t/strict.test以查看在设置 STRICT 模式或 TRADITIONAL 模式(这是 STRICT 的超集)后测试的所有案例。

您做了出色的研究和测试,但还有一些案例,例如:

  • 试图插入一个未定义的 ENUM 值。
  • 尝试为未定义 DEFAULT 的 NOT NULL 列插入默认值。
  • 尝试使用 CAST() 将字符串转换为整数等。
  • 如果您给出的长度大于 65536,则将 VARCHAR 转换为 MEDIUMTEXT 或 LONGTEXT。
  • 截断表和列的 COMMENT 字符串。
  • 将字符串转换为 YEAR 类型。
  • 定义具有重复条目的 SET 或 ENUM 列。

另外mysql-test/include/strict_autoinc.inc,因为它会在 auto-inc 值增长过大时测试溢出。

还有一些其他测试文件使用 STRICT 模式进行特定测试,但我没有检查它们。

于 2012-12-12T17:38:00.433 回答
4

我使用了 MySQL 5.5.28(社区服务器版)的源代码来查找正在使用的 STRICT_ALL_TABLES 的实例。

从我看到的情况来看,你的列表看起来已经很完整了,但下面是我学到的关于使用 STRICT_ALL_TABLES 的更多内容。第一个是另一个验证,而其余的都处理错误和警告。

  • 几何列不能有默认值。(sql/field.cc:9394)
  • 如果表注释超过 2048 个字符,MySQL 会产生错误而不是截断注释并发出警告。 (sql/unireg.cc:231)
  • 如果字段注释超过 1024 个字符,MySQL 会产生错误而不是截断注释并发出警告。 (sql/unireg.cc:739)
  • 在插入或更新时,如果 SET 或 ENUM 中存在重复值,MySQL 会产生错误而不是警告。 (sql/sql_table.cc:2503)
  • 有很多操作会在使用 STRICT_ALL_TABLES 发出警告时中止,而不是仅仅发出警告。这些对于我来说太多了,并且 abort_on_warning 标志的设置与创建警告的代码相去甚远,以至于我无法轻松记录(甚至理解)所有这些警告。但是如果有人想弄脏源代码,可以从sql/sql_update.cc:630sql/sql_insert.cc:841 开始
于 2012-12-12T18:49:17.173 回答