You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用Seeder填充数据时遇nvarchar转datetime类型错误

问题:Laravel Seeder向SQL Server填充数据时的类型转换错误

使用Laravel Seeder向SQL Server数据库填充数据时,反复遇到类型转换错误,报错信息为SQLSTATE[22007]:varchar数据类型转换为datetime数据类型时导致值超出范围。尝试将timestamps()替换为datetime()->nullable()后问题仍未解决,数据库管理工具使用SQL Server Management Studio。

相关迁移代码

public function up(): void
{
    Schema::create('books', function (Blueprint $table) {
        $table->id();
        $table->string('book_name');
        $table->string('author');
        $table->integer('page_count');
        $table->foreignId('category_id')->constrained()->onDelete('cascade');
        $table->string('isbn');
        $table->string('publisher');
        $table->string('publish_year');
        $table->string('status');
        $table->timestamps();
    });
}

错误详情

SQLSTATE[22007]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The conversion of a varchar data type to a datetime data type resulted in an out-of-range value. (Connection: sqlsrv, SQL: insert into [books] ([book_name], [author], [page_count], [category_id], [isbn], [publisher], [publish_year], [status], [updated_at], [created_at]) values (1984, George Orwell, 328, 4, 9780451524935, Penguin Books, 1949, available, 2025-03-17 14:01:33.722, 2025-03-17 14:01:33.722))


解决方案

1. 修正SQL Server连接配置

SQL Server默认日期格式可能与Laravel生成的YYYY-MM-DD HH:MM:SS.fff格式不兼容,修改config/database.php中的sqlsrv连接配置,明确日期处理规则:

'sqlsrv' => [
    'driver' => 'sqlsrv',
    'host' => env('DB_HOST', 'localhost'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'prefix' => '',
    'prefix_indexes' => true,
    'options' => [
        PDO::SQLSRV_ATTR_FORMAT_DECIMALS => true,
        PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true,
        'ReturnDatesAsStrings' => false,
    ],
],

2. 调整publish_year字段类型

当前publish_year为string类型,纯年份值(如1949)可能被SQL Server误识别为日期进行转换,建议改为integer类型:

// 替换原代码中的$table->string('publish_year');
$table->integer('publish_year');

同时更新Seeder中对应字段的值,确保传入整数类型而非字符串。

3. 统一Laravel时间戳格式

在AppServiceProvider的boot方法中,设置Carbon的序列化格式,确保与SQL Server兼容:

use Illuminate\Support\Carbon;

public function boot()
{
    Carbon::serializeUsing(function ($carbon) {
        return $carbon->format('Y-m-d H:i:s.u');
    });
}

4. 校验Seeder中的日期范围

确认Seeder生成的created_at/updated_at值在SQL Serverdatetime类型的合法范围内(1753-01-01 至 9999-12-31),使用now()或Carbon生成时间时,确保时区配置正确。


内容的提问来源于stack exchange,提问作者Ahmet Faruk Yaşar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:23:09