首页 > 解决方案 > 保存到 SQL Server 时 Laravel 日期时间格式不正确

问题描述

我正在开发一个在现有数据库上运行的项目。问题是在 SQL Server 中使用错误的格式插入日期时间列。服务器使用日期时间作为 Ymd,数据保存为 Ydm。

我做了一些测试,当保存到 MariaDB 时,日期时间被正确保存。

updated_at 和 created_at 有自定义字段,因此它们在模型上声明。

在模型中

class NotaFaturamento extends Model
{
    const CREATED_AT = 'DT_CADASTRO';
    const UPDATED_AT = 'DT_ATUALIZACAO';

这是保存数据后的 QueryLog 打印。正如您在查询日志中看到的,日期时间格式已正确解析为 SQL Server。

查询日志

在 Config\app.php

'timezone' => 'America/Sao_Paulo',
'locale' => 'pt-BR',

这是需要在 SQLServer 上配置的东西吗?我对此进行了很多搜索,但大多数回复都是关于 SQL Server 分隔符的。

我还在$dateFormat = 'Y-m-j h:i:s:000A';模型上声明了受保护但同样的问题发生了。存储 Carbon 对象时也存在此问题。

问候。

编辑

正如 Dan 所指出的,问题可能是 SQL Server 上的 DATEFORMAT 被用作 DMY。此外,正如@dns_nx指出的这个问题和回答的那样,有一种解决方法可以手动更改日期格式以保存在 SQL Server 上。

我已添加到我的模型中

public function getDateFormat()
{
   return 'Y-d-m H:i:s.v';
}

模型上的任何其他日期属性都应声明为日期:

protected $dates = ['DT_EMISSAO', 'DT_COMPETENCIA'];

我认为这不是解决问题的正确方法,但它确实有效。并且您可以创建@dns_nx 提到的另一个基本模型。

问候

标签: sql-serverlaraveldatetime

解决方案


我不能专门与 Laravel/Eloquent 交谈,但带有强类型datetime参数的参数化查询将正确保存该值。由于该值未正确保存,这是因为:

datetime1) 为某个参数类型提供的实际参数值错误

2) 参数类型为 (n)varchar,其值作为不符合 ISO 8601 格式的字符串传递

3) 参数作为不符合 ISO 8601 格式的字符串文字传递

要进行故障排除,请在您的开发数据库实例上运行 SQL 跟踪(扩展事件或探查器),包括捕获实际 SQL 查询的事件batch_completedrpc_completed这将确定上述哪个原因是罪魁祸首。将rpc_completed包括参数类型和值。请注意,对于 datetime 参数类型,跟踪将始终以YYYY-MM-DD hh:mm:ss.fff格式显示 datetime 值,这只是传递的实际二进制值的呈现。

如果参数类型为,则 SQL Server 将使用当前会话设置(n)varchar解析非 ISO 8601 日期时间字符串“2018-10-06 09:07:07.222” 。葡萄牙语登录DATEFORMAT的默认设置是但可以被先前在同一会话上执行的显式 SET 命令覆盖。使用字符串值 '2018-10-06 09:07:07.222',月份和日期部分将被解析为第 6 个月第 10 天。日期时间文字的解析方式类似。DATEFORMATDMYDATEFORMATDATEFORMAT DMY

快速搜索发现了这个问题。因此,如果您无法强制datetime应用程序传递强类型,则可以使用一种解决方法来datetime2(3)代替datetime. 无论会话设置如何, SQL Server 都会解析datetime2字符串“2018-10-06 09:07:07.222” 。我建议进行新开发,因为它不会将小数秒四舍五入到 1/300 单位,并在更小的空间中存储更高的精度值。YYYY-MM-DD hh:mm:ss.fffDATEFORMATdatetime2


推荐阅读