保存到SQL Server时Laravel日期时间格式不正确

时间:2018-10-06 12:35:58

标签: sql-server laravel datetime

我正在研究一个在现有数据库上运行的项目。问题是在SQL Server中使用错误的格式插入了datetime列。服务器将日期时间用作Y-m-d,数据将另存为Y-d-m。

我进行了一些测试,并且保存到MariaDB时的日期时间已正确保存。

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

在模型中

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

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

Querylog

在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。此外,正如this issue所指出并得到@dns_nx的回答,有一种解决方法可以手动更改dateformat以保存在SQL Server上。

我已添加到模型

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

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

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

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

致谢

1 个答案:

答案 0 :(得分:1)

我不能专门与Laravel / Eloquent对话,但是带有强类型nav_header_main.xml参数的参数化查询将正确保存该值。由于未正确保存该值,原因是:

1)为activity_talk.xml参数类型提供的实际参数值错误

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

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

要进行故障排除,请在您的dev数据库实例上运行SQL跟踪(扩展事件或Profiler),包括datetimedatetime事件,以捕获实际的SQL查询。这将确定是上述原因中的哪一个是罪魁祸首。 batch_completed将同时包含参数类型和值。请注意,使用datetime参数类型时,跟踪将始终以rpc_completed格式显示datetime值,这只是传递的实际二进制值的呈现。

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

快速搜索出现this issue。因此,如果您不能强制应用程序传递强类型的DATEFORMAT,则解决方法是使用datetime2(3)而不是DATEFORMAT DMY。无论会话datetime的设置如何,SQL Server都将datetime字符串'2018-10-06 09:07:07.222'解析为datetime2。我建议YYYY-MM-DD hh:mm:ss.fff用于新开发,因为它不会将小数秒舍入为1/300单位,并且可以在较小的空间中存储更高的精度值。