Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Konwersja MySQL do Doctrine Query Builder. Problemy z IF i CONCAT. Lub inne podejście do podzapytań dotyczących wyboru

OK, znalazłem rozwiązanie.

Możesz użyć CASE zamiast IF . Sprawdź to, ale kiedy używam CASE Nie mogę CONCAT moje pola:

$em = $this->getDoctrine()->getEntityManager();
$qb = $em->createQueryBuilder();
$q = $qb
      ->select("c.id")
      ->addSelect("CASE WHEN (c.parent IS NULL) THEN c.name ELSE 'something' END")
      ->from("MyBundle:Category", "c")
      ->leftJoin("c.parent", "t");

echo $q->getQuery()->getSQL();

Innym rozwiązaniem jest stworzenie własnej funkcji DQL, takiej jak IF i użyj go w ten sposób:

$em = $this->getDoctrine()->getEntityManager();
$qb = $em->createQueryBuilder();
$q = $qb
      ->select("c.id")
      ->addSelect("IF(c.parent IS NULL, c.name, CONCAT(CONCAT(t.name, ' / '), c.name))")
      ->from("MyBundle:Category", "c")
      ->leftJoin("c.parent", "t");

echo $q->getQuery()->getSQL();

Aby utworzyć ten IF, możesz przejść do tego linku i dowiedzieć się:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/ dql-doctrine-query-language.html#dodawanie-własnych-funkcji-do-języka-dql

Opublikuję tutaj moją klasę dla tego IF i config.yml, aby pomóc innym ludziom. Oto klasa IfFunction (otrzymałem ją od https://github.com/beberlei/DoctrineExtensions/blob/master/src/Query/Mysql/IfElse.php ):

<?php
namespace MyName\MiscBundle\Doctrine\ORM\Query\AST\Functions;

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

/**
 * Usage: IF(expr1, expr2, expr3)
 * 
 * If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2;
 * otherwise it returns expr3. IF() returns a numeric or string value,
 * depending on the context in which it is used. 
 * 
 * @author  Andrew Mackrodt <[email protected]>
 * @version 2011.06.19
 */
class IfFunction extends FunctionNode
{
    private $expr = array();

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->expr[] = $parser->ConditionalExpression();

        for ($i = 0; $i < 2; $i++)
        {
            $parser->match(Lexer::T_COMMA);
            $this->expr[] = $parser->ArithmeticExpression();
        }

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

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return sprintf('IF(%s, %s, %s)',
            $sqlWalker->walkConditionalExpression($this->expr[0]),
            $sqlWalker->walkArithmeticPrimary($this->expr[1]),
            $sqlWalker->walkArithmeticPrimary($this->expr[2]));
    }
}

Następnie musisz zaktualizować swój plik config.yml w ten sposób (po prostu dodałeś ostatnie 3 linie):

doctrine:
    dbal:
        driver:   "%database_driver%"
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8

    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        auto_mapping: true
        dql: #ADDED THIS LINE
            string_functions: #ADDED THIS LINE
                IF: MyName\MiscBundle\Doctrine\ORM\Query\AST\Functions\IfFunction #ADDED THIS LINE

Dzięki



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja MySQL COS() — zwraca cosinus liczby w MySQL

  2. Jak mogę stworzyć instalator dla strony internetowej. PHP mysql

  3. Jak mogę uzyskać autoinkrementowany identyfikator, gdy wstawiam rekord do tabeli za pomocą jdbctemplate?

  4. Wyczyść dane w tabeli MySQL za pomocą PHP?

  5. Jak zastąpić klucz podstawowy Django inną liczbą całkowitą, która jest unikalna dla tej tabeli?