启用严格模式时,MySQL会做什么验证?

时间:2012-12-10 22:41:53

标签: mysql validation strict

当MySQL允许我将NULL插入使用NOT NULL创建的字段时,我感到非常惊讶。我做了一些研究,发现了如何启用严格模式。但是,我不太确定启用STRICT_ALL_TABLES时MySQL的验证。

手册说:

  

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

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

  • 太长的字符串无效
  • 超出范围的数字无效
  • 非li NULL列的
  • NULL无效
  • TRUEFALSE似乎总是有效(分别为1和0)
  • 无效日期无效
  • 零日期有效(可以启用其他模式以更改此行为)
  • 整数字段中的浮点数有效(它们被舍入)
  • 数字字段中的字母无效

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

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

是否列出了MySQL执行的确切内容?

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

2 个答案:

答案 0 :(得分:8)

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

你做了很好的研究和测试,但还有一些案例,例如:

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

同样是mysql-test/include/strict_autoinc.inc,因为当auto-inc值变得太大时,它会测试溢出。

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

答案 1 :(得分:3)

我使用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:630 sql / sql_insert.cc:841