如何在Symfony3.4+Doctrine2.6的MS-SQL查询构造器中格式化日期
解决Doctrine查询构造器中MS-SQL日期格式化问题
嗨,这个问题我之前也碰到过!你用DATE_FORMAT没效果是因为它是MySQL专属的函数,而你用的是MS-SQL,得换用MS-SQL支持的日期格式化函数才行。下面给你几个可行的解决方案:
方案1:直接在查询构造器中使用MS-SQL的CONVERT函数
MS-SQL里用CONVERT来格式化日期,其中格式代码23对应yyyy-mm-dd(也就是你要的y-m-d格式)。修改你的查询代码如下:
$result->select("CONVERT(varchar, p.createdAt, 23) as createdAtFormatted") ->innerJoin('p.storeid', 'o') ->innerJoin('p.warehouseid', 'r') ->getQuery() ->execute();
这样查询结果里的createdAtFormatted字段就是直接格式化好的字符串了。
方案2:在实体类中添加自定义getter方法
如果不想在数据库层面处理,也可以保留查询返回的DateTime对象,在实体类里加一个专门的方法来格式化日期:
// 你的实体类(比如Product.php) class Product { // ... 其他属性和方法 /** * @ORM\Column(type="datetime") */ private $createdAt; // ... 原有的getCreatedAt方法 public function getCreatedAtFormatted(): string { return $this->createdAt->format('Y-m-d'); } }
之后查询返回实体对象后,直接调用$entity->getCreatedAtFormatted()就能得到格式化后的日期字符串了。这种方式更符合面向对象的设计,也方便后续修改格式。
方案3:注册Doctrine自定义DQL函数(适合频繁使用的场景)
如果你想在DQL里继续用DATE_FORMAT语法,可以注册一个自定义DQL函数,把它映射成MS-SQL的CONVERT。步骤如下:
- 创建自定义函数类:
// src/Doctrine/FunctionNode/DateFormat.php namespace App\Doctrine\FunctionNode; use Doctrine\ORM\Query\AST\Functions\FunctionNode; use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; class DateFormat extends FunctionNode { public $dateExpression; public $formatString; public function parse(Parser $parser) { $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); $this->dateExpression = $parser->ArithmeticPrimary(); $parser->match(Lexer::T_COMMA); $this->formatString = $parser->StringPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } public function getSql(SqlWalker $sqlWalker) { // 将DATE_FORMAT(date, '%Y-%m-%d')转换为CONVERT(varchar, date, 23) $formatMap = [ '%Y-%m-%d' => '23', // 可以添加其他格式映射 ]; $format = trim($this->formatString->value, "'"); $type = $formatMap[$format] ?? '23'; return "CONVERT(varchar, " . $this->dateExpression->dispatch($sqlWalker) . ", " . $type . ")"; } }
- 在Symfony的
config.yml中配置Doctrine:
doctrine: orm: # ... 其他配置 dql: string_functions: DATE_FORMAT: App\Doctrine\FunctionNode\DateFormat
之后你就可以像原来那样在查询构造器里用DATE_FORMAT(p.createdAt, '%Y-%m-%d')了,Doctrine会自动把它转换成MS-SQL的CONVERT语句。
内容的提问来源于stack exchange,提问作者prabhat kumar jena
相关产品推荐
相关产品推荐

