我正在尝试将这个有效的MySQL查询转换为DQL查询,但我在使用DQL中的CONCAT函数(可能)时遇到了问题。据我所知,DQL中的CONCAT功能只能接受两个参数,但我需要三个参数,经过搜索后我找到了这个解决方案 - NESTED CONCAT :
需要将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解决方案 NESTED 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'
编辑:通过@Alvin Bunk的提案尝试了这个DQL查询但没有任何成功:
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'
修改 我开始认为这个问题来自 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"
}
}
解决方案:
问题出在(+ INTERVAL 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 :(得分:2)
尝试在主查询周围使用双引号。我认为它看到&#34; \&#34;作为下一行并给出该错误。
更新了以下内容:
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();
再试一次!
答案 1 :(得分:0)
解决方案:
问题出现在(+ INTERVAL 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();
}