【问题标题】:why mysql accept null for non-nullable fields为什么 mysql 为不可为空的字段接受 null
【发布时间】:2016-03-19 07:48:41
【问题描述】:

我正在通过laracast fundamentals series 学习 laravel 5.1,在第 7 集中讨论迁移,我构建了一个这样的迁移表:

public function up()
{
    Schema::create('articles', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('body');
        $table->timestamps();
        $table->timestamp('published_at');
    });
}

正如它在第 10 集中所说,当我通过没有 published_at 时间戳字段的表单将文章添加到数据库时,这应该不起作用,并且应该通过 Not Null constraint failed 的异常但是令人难以置信的文章添加到表中。 当我查看 phpmyadmin 结构中 published_at 列的表时,它没有选中 null 复选框,所以它不应该接受 null 吗? 这是真的吗?
但后来我注意到迁移将published_at 列的默认值设置为0000-00-00 00:00:00为什么?!这会覆盖NULL条件吗? 然后我尝试将默认值设置为none,但仍然没有检查空值。我再次尝试添加没有published_at 字段的文章但又在表中添加了一个新行,published_at 值设置为0000-00-00 00:00:00。 有什么解释吗?


我正在使用 wampserver 和 mysql v5.6.17php v5.5.12

【问题讨论】:

    标签: php mysql laravel laravel-5 laravel-5.1


    【解决方案1】:

    所有数据库类型都有默认值。当您创建记录并仅填写标题时,正文将设置为空字符串,并将时间戳设置为“空”日期,即0000-00-00 00:00:00。如果您将这些字段设置为可为空并为它们设置 ->default(null),那么在这种情况下,它们将具有空值。

    您还可以阅读Default values for types in MySql

    【讨论】:

    • 谢谢 Marcin,我的表单中没有 published_at 的文本框,所以当我提交时,查询中的不是 null 吗?还是会是一个空字符串?
    • 而且我没有将该字段设置为nullable
    • @osyan 如果您的published_at 不可为空,则当您不填写它时,您将得到0000-00-00 00:00:00,因为您没有设置任何其他默认值。您可以使用->default(DB::raw('CURRENT_TIMESTAMP')) 设置它,然后当您不填写它时,您将默认获得当前日期和时间而不是零
    • 我明白了,但我仍然很困惑为什么在相同的情况下它会通过该视频中的异常出现。这可能是因为 sqlite 和 mySql 之间的差异吗?
    • @osyan 我明白了,但我不知道为什么会这样。我几乎一直在使用 MySql,不幸的是没有更多的时间来测试它。
    【解决方案2】:

    SELECT @@SQL_MODE;.

    如果您没有看到 Strict SQL Modes 之一启用,则 MySQL 正在使用其旧行为,并将无效值强制转换为有效值以允许插入行。

    如果严格模式未生效,MySQL 会为无效或缺失值插入调整值并产生警告。

    官方 MySQL Server 5.6 附带的默认配置文件启用了STRICT_TRANS_TABLES。 WAMP 可能没有遵循相同的约定,也许是出于向后兼容的原因……但可以更改配置。

    【讨论】:

    猜你喜欢
    • 2017-12-25
    • 1970-01-01
    • 2021-05-21
    • 2021-08-06
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    相关资源
    最近更新 更多