【问题标题】:Laravel Incorrect date value sql_mode emptyLaravel 错误的日期值 sql_mode 为空
【发布时间】:2017-06-02 15:27:32
【问题描述】:

我在使用 Laravel 的查询生成器 (DB Facade) 执行 sql 更新/插入时遇到问题。在表格中插入一行时,我得到了

QueryException:日期时间格式无效:1292 日期值不正确: “FoundationDate”列的“0000-00-00”。

当我将 SQL 语句复制到 PHPMyAdmin 时,它可以正常工作。我知道这取决于sql_mode 设置。我检查了这个变量,没有启用严格模式!那么它怎么可能在 PHPMyAdmin 上工作,但在 Laravel 却不行呢?

我正在使用 Mysql 5.5.49 和 Laravel 5.3。

提前致谢!

【问题讨论】:

  • 你在哪里检查变量?可以为当前会话设置该值,一个体面的框架应该总是这样做。不管怎样,我认为一开始就防止无效日期发生会不会那么麻烦。
  • 在 PhpMyAdmin 中,您可以检查变量值(选项卡“变量”)。变量 sql_mode 为空。
  • PhpMyAdmin 不是您的 Laravel 应用程序的一部分,因此它将建立自己的数据库连接。您需要验证来自 PHP 本身的值。
  • 我会澄清一下:转到“搜索/在文件中查找”并在整个代码库中查找字符串“sql_mode”。

标签: mysql sql laravel laravel-5 laravel-5.3


【解决方案1】:

Laravel DB 插入,不像 eloquent 不会为你创建日期。由于您的表中有FoundationDate 是日期时间类型,因此您必须手动设置它。

DB::table("users")->insert([
    ...
    'FoundationDate' => \Carbon\Carbon::now()
]);

【讨论】:

  • 我的值 '0000-00-00' 来自另一个来源,以后在数据库中应该是 '0000-00-00'。
  • 好吧,'0000-00-00' 不是正确的日期时间字符串。所以 laravel 默认是不会插入的;您可以添加到您的模型protected $timestamps = false;
  • 列类型为date。对于这种类型,只要禁用严格模式,它就是正确的日期值。 PHPMyAdmin 接受它,只有 Laravel 抛出异常(实际上来自 mysql)。
  • 您是否在迁移中创建了nullable() 属性?
  • 你说的类型是date。您的错误另有说明。 QueryException: Invalid "datetime" format。我的猜测是迁移中的某些东西。
【解决方案2】:

对于 Laravel 5.3 sql_mode 由 Illuminate\DatabaseConnectors\MySqlConnector@setModes 在运行时设置:

/**
 * Set the modes for the connection.
 *
 * @param  \PDO  $connection
 * @param  array  $config
 * @return void
 */
protected function setModes(PDO $connection, array $config)
{
    if (isset($config['modes'])) {
        $modes = implode(',', $config['modes']);

        $connection->prepare("set session sql_mode='{$modes}'")->execute();
    } elseif (isset($config['strict'])) {
        if ($config['strict']) {
            $connection->prepare("set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'")->execute();
        } else {
            $connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
        }
    }
}

注意 sql_mode 的 NO_ZERO_DATE 是在该方法中设置的。可以在 config.database.php 文件中更改 sql_mode,方法是在 mysql 连接中添加 modes 键,如下所示:

'connections' => [
    'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'charset' => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
        'modes'  => [],
    ],
]

您可以将modes 保留为空数组,也可以根据需要对其进行配置。更多信息here

或者,您可以设置strict => false,

【讨论】:

  • strict => false, 就是这样。谢谢你,先生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-26
  • 2017-08-05
相关资源
最近更新 更多