我在Laravel上的Web应用程序上工作,它依赖于Doctrine。数据库存储在SQL Express 2017上。
当我执行SELECT时,我在documentation中提到了DateTime类型的问题。
无法将数据库值“2018-11-19 16:19:44.923”转换为Doctrine Type datetimetz。预期格式:Y-m-d H:i:s.u P.
为了解决这个问题,经过一番研究后我创建了自己的DateTime类型。
<?php
namespace App\Doctrine\Types;
use Doctrine\DBAL\Types\DateTimeType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
class MsDateTime extends DateTimeType
{
private $dateTimeFormatString = 'Y-m-d H:i:s.u';
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return ($value !== null) ? $value->format($this->dateTimeFormatString) : null;
}
}
然后我覆盖默认类型:
Type::overrideType(Type::DATETIMETZ, 'App\Doctrine\Types\MsDateTime');
所以现在我可以显示数据,但是我无法插入新行:执行'INSERT INTO表(row1,row2,active,date_created,timestamp)VALUES(?,?,?,?,?)'时出现异常[“测试”,“测试”,1,“2018-11-20 16:12:11.349245”,“2018-11-20 16:12:11.349250”]
我想知道为什么我不能存储新行。如果您对SQLServer的Doctrine有任何修复,我将非常感激!
我们还使用Python和SQLAlchemy来查询同一个数据库,我们没有这种问题。
使用Microsoft Sql Server Express 2017,您应首先验证是否在Doctrine配置/自动加载器中使用SQLServer2012Platform
。
我用以下方式指定它(在Codeigniter下):
$myPlatform = new \Doctrine\DBAL\Platforms\SQLServer2012Platform();
$connectionOptions = array(
'driver' => 'pdo_sqlsrv',
'user' => $db['default']['username'],
'password' => $db['default']['password'],
'host' => $db['default']['hostname'],
'dbname' => $db['default']['database'],
'platform' => $myPlatform
);
我将所有SQL字段从DATETIME
切换到DATETIME2
,插入/更新运行良好。
我的Doctrine实体用'datetime'类型定义,我可以用本机DateTime()
对象提供它们。
/**
* @var \DateTime
*
* @ORM\Column(type="datetime", nullable = true)
*/
protected $created;
/**
* @var \DateTime
*
* @ORM\Column(type="datetime", nullable = true)
*/
protected $updated;
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updatedTimestamps(): void
{
if ($this->created === null) {
$this->created = new \DateTime();
}
$this->updated = new \DateTime();
}
希望这可以帮助!
根据已知问题,我将放弃datetimetz类型。见Doctrine - Known Vendor Issues - Microsoft SQL Server
我应该展示我的代码。所以我删除了我的自定义类型并切换到SQL Server中的DateTime2。
我可以选择没有任何问题的数据,但我无法插入。
这是我的类User的构造函数,例如:
/**
* @ORM\Column(type="datetimetz", name="date_created")
*/
protected $date_created;
public function __construct($name, $firstname, $age) {
$this->name=$name;
$this->firstname=$firstname;
$this->age = $age;
$this->date_created = setDatetime("UTC");
}
public function setDateTime($tz="UTC") {
return new DateTime("now", new DateTimeZone($tz));
}