2016-06-02 4 views
0

Я пытаюсь преобразовать этот рабочий запрос MySQL в DQL-запрос, но мне грозит проблема использования функции CONCAT (возможно) в DQL. Как я знаю, что функция CONCAT в DQL может принимать только два параметра, но мне нужны три параметра и после поиска я нашел это решение - NESTED CONCAT:Преобразование запроса, включая MySQL CONCAT с тремя параметрами в DQL Query (два параметра)

MySQL запрос, необходимый для преобразования в DQL:

SET @new_booking_pickup_date = '2016-04-01'; 
SET @new_booking_pickup_time = '12:00:00'; 
SET @new_booking_return_date = '2016-05-01'; 
SET @new_booking_return_time = '13:00:00'; 

SELECT * FROM Reservation WHERE NOT ( 

CONCAT(@new_booking_pickup_date,' ',@new_booking_pickup_time) > CONCAT(return_date,' ',return_time) + INTERVAL 0 DAY 
OR 
CONCAT(@new_booking_return_date,' ',@new_booking_return_time) < CONCAT(pickup_date,' ',pickup_time) + INTERVAL 0 DAY 
); 

вот DQL решение, что я пытаюсь с вложенными CONCAT:

return $this->getEntityManager() 
    ->createQuery(
     'SELECT id, licensePlate, 

     (SELECT car1.model FROM AppBundle:Car car1 WHERE car1.id = car.id) AS model_id, 
     (SELECT car2.brand FROM AppBundle:Car car2 WHERE car2.id = car.id) AS brand_id, 

     (SELECT carmodel.model FROM AppBundle:CarModel carmodel WHERE carmodel.id = model_id) AS model_name, 
     (SELECT carbrand.brand FROM AppBundle:CarBrand carbrand WHERE carbrand.id = brand_id) AS brand_name 

      FROM AppBundle:Car car WHERE IDENTITY(car.id) NOT IN (

      SELECT IDENTITY(reservation.car) FROM AppBundle:Reservation reservation WHERE NOT (

       CONCAT(CONCAT(:pickupDate, \' \'),:pickupTime) > CONCAT(CONCAT(reservation.returnDate, \' \'),reservation.returnTime) + INTERVAL 0 DAY 
      OR 
       CONCAT(CONCAT(:returnDate, \' \'),:returnTime) < CONCAT(CONCAT(reservation.pickupDate, \' \'),reservation.pickupTime) + INTERVAL 0 DAY 

      ) 


      )' 
    ) 
    ->setParameter('pickupDate', $pickupDate) 
    ->setParameter('returnDate', $returnDate) 
    ->setParameter('returnTime', $returnTime) 
    ->setParameter('pickupTime', $pickupTime) 
    ->getResult(); 

Вот результат после выполнения запроса DQL - Исключение !!!:

[Syntax Error] line 0, col 831: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '0' 

EDIT: Пробовал этот DQL запрос без какого-либо успеха по предложению @Alvin двухъярусной:

return $this->getEntityManager() 
     ->createQuery(
      "SELECT car.id AS car_id, 

      (SELECT IDENTITY(car1.model) FROM AppBundle:Car car1 WHERE car1.id = car.id) AS model_id, 
      (SELECT IDENTITY(car2.brand) FROM AppBundle:Car car2 WHERE car2.id = car.id) AS brand_id, 

      (SELECT carmodel.model FROM AppBundle:CarModel carmodel WHERE carmodel.id = model_id) AS model_name, 
      (SELECT carbrand.brand FROM AppBundle:CarBrand carbrand WHERE carbrand.id = brand_id) AS brand_name 

       FROM AppBundle:Car car WHERE IDENTITY(car.id) NOT IN (

       SELECT IDENTITY(reservation.car) FROM AppBundle:Reservation reservation WHERE NOT (

        CONCAT(CONCAT(:pickupDate,' '),:pickupTime) > CONCAT(CONCAT(reservation.returnDate,' '),reservation.returnTime) + INTERVAL 0 DAY 
       OR 
        CONCAT(CONCAT(:returnDate,' '),:returnTime) < CONCAT(CONCAT(reservation.pickupDate,' '),reservation.pickupTime) + INTERVAL 0 DAY 

       ) 


       )" 
     ) 
     ->setParameter('pickupDate', $pickupDate) 
     ->setParameter('returnDate', $returnDate) 
     ->setParameter('returnTime', $returnTime) 
     ->setParameter('pickupTime', $pickupTime) 
     ->getResult(); 

Здесь я использую двойные кавычки вокруг основного запроса и одиночные кавычки в CONCAT функция. Я получаю то же сообщение об ошибке:

[Syntax Error] line 0, col 849: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got '0' 

EDIT: Я начинаю думать, что проблема исходит от функции NESTED CONCAT, но я проверил его в консоли, и это работает идеально - здесь результат:

php app/console doctrine:query:dql "SELECT CONCAT(CONCAT(car.licensePlate,' '),car.deposit) FROM AppBundle:Car car" 

array(4) { 
    [0]=> 
    array(1) { 
    [1]=> 
    string(10) "B0001HA 20" 
    } 
    [1]=> 
    array(1) { 
    [1]=> 
    string(10) "B0002HA 20" 
    } 
    [2]=> 
    array(1) { 
    [1]=> 
    string(10) "B0003HA 30" 
    } 
    [3]=> 
    array(1) { 
    [1]=> 
    string(10) "B0004HA 40" 
    } 
} 

решение:

проблема заключалась в (+ ПЕРИОД AL 0 DAY) - он не поддерживается DQL, в этом случае мне он даже не нужен, потому что мои поля уже имеют тип DATE и TIME.

public function getCarsNotInRange($pickupDate, $pickupTime, $returnDate, $returnTime) 
    { 
     return $this->getEntityManager() 
      ->createQuery(
       " 
       SELECT car.id, car.licensePlate, 

       (SELECT IDENTITY(car1.model) FROM AppBundle:Car car1 WHERE car1.id = car.id) AS model_id, 
       (SELECT IDENTITY(car2.brand) FROM AppBundle:Car car2 WHERE car2.id = car.id) AS brand_id, 

       (SELECT carmodel.model FROM AppBundle:CarModel carmodel WHERE carmodel.id = model_id) AS model_name, 
       (SELECT carbrand.brand FROM AppBundle:CarBrand carbrand WHERE carbrand.id = brand_id) AS brand_name 

        FROM AppBundle:Car car WHERE car.id NOT IN 
        (
        SELECT IDENTITY(reservation.car) FROM AppBundle:Reservation reservation WHERE NOT 
         (
          CONCAT(CONCAT(:pickupDate, ' '),:pickupTime) > CONCAT(CONCAT(reservation.returnDate, ' '),reservation.returnTime) 
        OR 
          CONCAT(CONCAT(:returnDate, ' '),:returnTime) < CONCAT(CONCAT(reservation.pickupDate, ' '),reservation.pickupTime) 
        ) 
       ) 

     ") 
      ->setParameter('pickupDate', $pickupDate) 
      ->setParameter('returnDate', $returnDate) 
      ->setParameter('returnTime', $returnTime) 
      ->setParameter('pickupTime', $pickupTime) 
      ->getResult(); 
    } 
+0

Вы не нашли закрывающую скобку – Li357

+0

Я не могу понять, что именно проблема – eXtreme

+0

я только что дал вам ответ.Это синтаксическая ошибка, потому что вам не хватает закрывающей скобки – Li357

ответ

0

Решение:

Проблема заключалась в (+ ИНТЕРВАЛ 0 DAY) - это не поддерживается DQL, в данном случае я даже не нужно, потому что мои поля уже типа DATE и TIME ,

public function getCarsNotInRange($pickupDate, $pickupTime, $returnDate, $returnTime) 
    { 
     return $this->getEntityManager() 
      ->createQuery(
       " 
       SELECT car.id, car.licensePlate, 

       (SELECT IDENTITY(car1.model) FROM AppBundle:Car car1 WHERE car1.id = car.id) AS model_id, 
       (SELECT IDENTITY(car2.brand) FROM AppBundle:Car car2 WHERE car2.id = car.id) AS brand_id, 

       (SELECT carmodel.model FROM AppBundle:CarModel carmodel WHERE carmodel.id = model_id) AS model_name, 
       (SELECT carbrand.brand FROM AppBundle:CarBrand carbrand WHERE carbrand.id = brand_id) AS brand_name 

        FROM AppBundle:Car car WHERE car.id NOT IN 
        (
        SELECT IDENTITY(reservation.car) FROM AppBundle:Reservation reservation WHERE NOT 
         (
          CONCAT(CONCAT(:pickupDate, ' '),:pickupTime) > CONCAT(CONCAT(reservation.returnDate, ' '),reservation.returnTime) 
        OR 
          CONCAT(CONCAT(:returnDate, ' '),:returnTime) < CONCAT(CONCAT(reservation.pickupDate, ' '),reservation.pickupTime) 
        ) 
       ) 

     ") 
      ->setParameter('pickupDate', $pickupDate) 
      ->setParameter('returnDate', $returnDate) 
      ->setParameter('returnTime', $returnTime) 
      ->setParameter('pickupTime', $pickupTime) 
      ->getResult(); 
    } 
1

Попробуйте вместо этого использовать двойные кавычки вокруг основного запроса. Я думаю, что он видит «\» в качестве следующей строки и дает эту ошибку.

Обновленный ниже:

return $this->getEntityManager() 
    ->createQuery(
     "SELECT id, licensePlate, 
     (SELECT car1.model FROM AppBundle:Car car1 WHERE car1.id = car.id) AS model_id, 
     (SELECT car2.brand FROM AppBundle:Car car2 WHERE car2.id = car.id) AS brand_id, 
     (SELECT carmodel.model FROM AppBundle:CarModel carmodel WHERE carmodel.id = model_id) AS model_name, 
     (SELECT carbrand.brand FROM AppBundle:CarBrand carbrand WHERE carbrand.id = brand_id) AS brand_name 
     FROM AppBundle:Car car 
      WHERE IDENTITY(car.id) NOT IN (
      SELECT IDENTITY(reservation.car) FROM AppBundle:Reservation reservation WHERE NOT (
       CONCAT(:pickupDate, \' \', :pickupTime) > CONCAT(reservation.returnDate, \' \', reservation.returnTime) + INTERVAL 0 DAY 
      OR 
       CONCAT(:returnDate, \' \',:returnTime) < CONCAT(reservation.pickupDate, \' \',reservation.pickupTime) + INTERVAL 0 DAY 
      ) 
      )" 
    ) 
    ->setParameter('pickupDate', $pickupDate) 
    ->setParameter('returnDate', $returnDate) 
    ->setParameter('returnTime', $returnTime) 
    ->setParameter('pickupTime', $pickupTime) 
    ->getResult(); 

Попробуйте еще раз!

+0

Я обновил вопрос - все еще не работал. Я думаю, проблема связана с функцией CONCAT. Я успешно протестировал функцию CONCAT на консоли, и это успешно конкатенация. – eXtreme

+0

Я обновил свой код и удалил внутри concat. возможно, это проблема - попробуйте и посмотрите, работает ли это! –

+0

Не работает снова. Насколько я знаю, функция DQL CONCAT не работала с тремя параметрами, она будет принимать только две. Вот почему я использую вложенный CONCAT. См. Мой рабочий стол DQL-запроса с NESTED CONCAT в редакторе. – eXtreme