Doctrine2 DQL 查询上排序的 CASTING 属性

发布于 2024-12-04 12:25:24 字数 395 浏览 1 评论 0原文

我正在尝试获取 Doctrine2 实体,按其 ID 排序,该 ID 显然是一个字符串,尽管它只包含数字。 所以我想做的是这样的:

SELECT entity1, cast (entity1.id AS integer) AS orderId
FROM Namespace\Bla\MyEntity 
ORDER BY orderId

有没有办法在Doctrine2中做这样的事情? 或者,如果我无法更改 id 的类型(当然是由于客户要求),获取结果的最佳实践是什么?


注意:我不是在问 SQL 代码,我是在要求 Doctrine2 解决方案,最好是 DQL

I am trying to get Doctrine2 Entities, ordered by their ID which apparently is a String even though it contains only Numbers.
So what I would like to do is something like this:

SELECT entity1, cast (entity1.id AS integer) AS orderId
FROM Namespace\Bla\MyEntity 
ORDER BY orderId

Is there a way to do something like this in Doctrine2?
Or, what would be the best practise to get my Result if i can't change the type of the id (due to customer requirements of course)?


Attention: I am not asking SQL Code, i am asking for a Doctrine2 Solution, preferably in DQL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

卖梦商人 2024-12-11 12:25:25

根据 Jasper N. Brouwer 的回答,这是一个稍微增强的解决方案:

namespace MyProject\Query;
    
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
    
class Cast extends FunctionNode
{
  /** @var \Doctrine\ORM\Query\AST\PathExpression */
  protected $first;
  /** @var string */
  protected $second;

  /**
   * @param SqlWalker $sqlWalker
   *
   * @return string
   */
  public function getSql(SqlWalker $sqlWalker)
  {
    return sprintf(
      "CAST(%s AS %s)",
      $this->first->dispatch($sqlWalker),
      $this->second
    );
  }
   
  /**
   * @param Parser $parser
   *
   * @return void
   */
  public function parse(Parser $parser)
  {
    $parser->match(Lexer::T_IDENTIFIER);
    $parser->match(Lexer::T_OPEN_PARENTHESIS);
    $this->first = $parser->ArithmeticPrimary();
    $parser->match(Lexer::T_AS);
    $parser->match(Lexer::T_IDENTIFIER);
    $this->second = $parser->getLexer()->token['value'];
    $parser->match(Lexer::T_CLOSE_PARENTHESIS);
  }
}

现在应该可以像这样编写 DQL:

SELECT e, CAST(e.id AS integer) AS HIDDEN orderId
FROM Namespace\Bla\MyEntity e ORDER BY orderId

Based on Jasper N. Brouwer answer, this is a little bit enhanced solution:

namespace MyProject\Query;
    
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
    
class Cast extends FunctionNode
{
  /** @var \Doctrine\ORM\Query\AST\PathExpression */
  protected $first;
  /** @var string */
  protected $second;

  /**
   * @param SqlWalker $sqlWalker
   *
   * @return string
   */
  public function getSql(SqlWalker $sqlWalker)
  {
    return sprintf(
      "CAST(%s AS %s)",
      $this->first->dispatch($sqlWalker),
      $this->second
    );
  }
   
  /**
   * @param Parser $parser
   *
   * @return void
   */
  public function parse(Parser $parser)
  {
    $parser->match(Lexer::T_IDENTIFIER);
    $parser->match(Lexer::T_OPEN_PARENTHESIS);
    $this->first = $parser->ArithmeticPrimary();
    $parser->match(Lexer::T_AS);
    $parser->match(Lexer::T_IDENTIFIER);
    $this->second = $parser->getLexer()->token['value'];
    $parser->match(Lexer::T_CLOSE_PARENTHESIS);
  }
}

Now it should be possible to write DQL like this:

SELECT e, CAST(e.id AS integer) AS HIDDEN orderId
FROM Namespace\Bla\MyEntity e ORDER BY orderId
愛放△進行李 2024-12-11 12:25:25

认为在这种情况下最好使用一些额外的功能(而不是试图“规避”他们的功能)。例如,为 Doctrine 2 添加几乎所有必需的(不支持开箱即用的)内容的优秀解决方案是 Beberlei 的 DoctrineExtensions (github)。有了它,就可以像OP的情况一样直接使用CAST语句:(

“Symfony-example”)例如在你的config.xml中添加行:

orm:
    ..
    entity_managers:
            ....
            dql:
                ....
                string_functions:
                    CAST: DoctrineExtensions\Query\Mysql\Cast

然后你就可以使用它喜欢:

 SELECT entity1, CAST(entity1.id AS integer) AS orderId
 FROM Namespace\Bla\MyEntity 
 ORDER BY orderId

Think it's better to use some extra functional in such cases ( without trying "to circumvent" theirs). E.g. an excellent solution adding almost all necessary ( not supported out of the box ) stuff for Doctrine 2 is DoctrineExtensions by beberlei (github). With it it's possible to use directly CAST-statement like in OP's case:

("Symfony-example") E.g. in your config.xml add lines:

orm:
    ..
    entity_managers:
            ....
            dql:
                ....
                string_functions:
                    CAST: DoctrineExtensions\Query\Mysql\Cast

Then U can use it like:

 SELECT entity1, CAST(entity1.id AS integer) AS orderId
 FROM Namespace\Bla\MyEntity 
 ORDER BY orderId
泪痕残 2024-12-11 12:25:25

在不改变数据类型的情况下尝试一下这个

  select (entity1 * 1) as display_value, entity1 as return_value 
      from Table_Name
     order by 1 asc;

Try this one by with out changing the data type

  select (entity1 * 1) as display_value, entity1 as return_value 
      from Table_Name
     order by 1 asc;
楠木可依 2024-12-11 12:25:25

不确定这是否有效,但要访问实体 ID,您需要 IDENTITY() DQL 函数。试试这个:

SELECT entity1  FROM Namespace\Bla\MyEntity  ORDER BY IDENTITY(entity1)

Not sure if this works, but to access an entity ID you need the IDENTITY() DQL function. Try this:

SELECT entity1  FROM Namespace\Bla\MyEntity  ORDER BY IDENTITY(entity1)
弥枳 2024-12-11 12:25:25

我认为您想要entity1订购。如果您的ENTITY1数据类型是整数,则无需将其更改为整数,或者不需要将其更改为Integer。以下是您的查询。

select entity1,cast(entity1 as integer) as order_id from Table_Name order by 1 asc;

I think you want order by entity1. if your entity1 data type is integer then no need to change it into integer or if it is not then you should do it. below is query for you.try this one.

select entity1,cast(entity1 as integer) as order_id from Table_Name order by 1 asc;
高跟鞋的旋律 2024-12-11 12:25:25

我昨天刚刚在自己的代码中做了类似的事情。我能够做到:

select cast(entity1 as int) as OrderID
from yourtablename
where yourconditions

我必须将我的钱实际铸造为金钱,然后是整数,但如果你没有小数,你就不应该遇到这个问题。您还可以尝试将其转换为数字或使用转换而不是转换,但在这种情况下转换更好。

如果 OrderID 中已具有相同的值,为什么还需要实体 1 作为列?

I just did something similar in my own code yesterday. I was able to do:

select cast(entity1 as int) as OrderID
from yourtablename
where yourconditions

I had to actually cast mine as money and then int, but if you don't have a decimal, you should not have that issue. You can also try casting as numeric or using convert instead of cast, but cast is better in this situation.

Why do you need entity1 as a column if you already have the same value in OrderID?

妄想挽回 2024-12-11 12:25:24

您应该能够 添加您自己的函数来实现此功能。

该类看起来像这样:

namespace MyProject\Query;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;

class CastAsInteger extends FunctionNode
{
    public $stringPrimary;

    public function getSql(SqlWalker $sqlWalker)
    {
        return 'CAST(' . $this->stringPrimary->dispatch($sqlWalker) . ' AS integer)';
    }

    public function parse(Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->stringPrimary = $parser->StringPrimary();

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }
}

您需要注册您的函数:

$config = $em->getConfiguration();
$config->addCustomNumericFunction('INT', CastAsInteger::class);

然后您可以使用它:

SELECT e, INT(e.id) AS HIDDEN orderId
FROM Namespace\Bla\MyEntity e
ORDER BY orderId

PS:通过添加 HIDDEN 关键字,别名 orderId 将不会出现' t 出现在结果中(并且仅用于排序)。

You should be able to add your own function to implement this feature.

The class would look something like this:

namespace MyProject\Query;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;

class CastAsInteger extends FunctionNode
{
    public $stringPrimary;

    public function getSql(SqlWalker $sqlWalker)
    {
        return 'CAST(' . $this->stringPrimary->dispatch($sqlWalker) . ' AS integer)';
    }

    public function parse(Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->stringPrimary = $parser->StringPrimary();

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }
}

You'll need to register your function:

$config = $em->getConfiguration();
$config->addCustomNumericFunction('INT', CastAsInteger::class);

Then you can use it:

SELECT e, INT(e.id) AS HIDDEN orderId
FROM Namespace\Bla\MyEntity e
ORDER BY orderId

PS: By adding the HIDDEN keyword, the alias orderId won't be in the results (and is only used for ordering).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文