Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Chuyển đổi MySQL thành Doctrine Query Builder. Vấn đề với IF và CONCAT. Hoặc một cách tiếp cận khác cho các truy vấn phụ trên lựa chọn

Được rồi, tôi đã tìm ra giải pháp.

Bạn có thể sử dụng CASE thay vì IF . Hãy kiểm tra điều này, nhưng khi tôi đang sử dụng CASE Tôi không thể CONCAT lĩnh vực của tôi:

$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();

Một giải pháp khác là tạo hàm DQL của riêng bạn, như IF và sử dụng nó như thế này:

$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();

Để tạo NẾU này, bạn có thể truy cập liên kết này và tìm hiểu: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/ dql-doct-query-language.html # add-your-own-functions-to-the-dql-language

Tôi sẽ đăng ở đây lớp của tôi cho IF này và config.yml để giúp những người khác. Đây là lớp IfFunction (Tôi lấy nó từ 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]));
    }
}

Sau đó, bạn cần cập nhật config.yml của mình như thế này (chỉ thêm 3 dòng cuối cùng):

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

Cảm ơn



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tạo một bảng với các tên cột bắt nguồn từ các giá trị hàng của một bảng khác

  2. MySQL - GROUP BY với ORDER DESC không hoạt động

  3. Người theo dõi / cấu trúc cơ sở dữ liệu sau

  4. CHÈN BỎ QUA bằng Laravel's Fluent

  5. Làm thế nào để gọi thủ tục lưu trữ MySQL từ Rails?