es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Error de sintaxis: línea 0, col 152: Error: Se esperaba =, <, <=, <>, >, >=, !=, y se obtuvo ‘BETWEEN’

Cuando intento ejecutar el siguiente código:

return $this->createQueryBuilder('e')
    ->select('e.user_id', 'e.year', 'e.week_number', 'e.approved_by')
    ->where('e.user_id = :userID')
    ->andWhere('(e.year * 100 + e.week_number) BETWEEN :startDate and :endDate')
    ->setParameter('userID', $userID)
    ->setParameter('startDate', ($startYear * 100 + $startWeek))
    ->setParameter('endDate', ($endYear * 100 + $endWeek))
    ->getQuery()
    ->getResult();

Obtengo el siguiente error: [Error de sintaxis] línea 0, col 149: Error: Se esperaba =, <, <=, <>, >, >=, !=, se recibió 'BETWEEN'.

Si imprimo mi consulta, se ve así:

dql: "SELECT e.user_id, e.year, e.week_number, e.approved_by FROM App\Entity\... e WHERE e.user_id = :userID AND ((e.year * 100 + e.week_number) BETWEEN :startDate and :endDate)"

Si uso esta consulta en SSMS y reemplazo las variables con los datos reales, funciona perfectamente.

Mis variables tienen los siguientes valores:

$startYear = 2021;
$startWeek = 52;
$endYear = 2022;
$endWeek = 05;

// :startDate = 202152;
// :endDate = 202205;

Los cálculos probablemente rompen el generador de consultas. Principalmente porque hago consultas similares: ->andWhere('e.week_number between :startWeek and :endWeek') que sí funcionan. No sé cómo solucionarlos o por qué ocurre esto.

Estoy usando Symfony 4.4. SQL Server para mi base de datos.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El error indica que la palabra clave BETWEEN no es reconocida por el generador de consultas, probablemente porque no es universalmente compatible en todas las plataformas de base de datos. Una posible solución alternativa es utilizar >= y <= en lugar de BETWEEN, de esta manera:

    return $this->createQueryBuilder('e')
        ->select('e.user_id', 'e.year', 'e.week_number', 'e.approved_by')
        ->where('e.user_id = :userID')
        ->andWhere('(e.year * 100 + e.week_number) >= :startDate')
        ->andWhere('(e.year * 100 + e.week_number) <= :endDate')
        ->setParameter('userID', $userID)
        ->setParameter('startDate', ($startYear * 100 + $startWeek))
        ->setParameter('endDate', ($endYear * 100 + $endWeek))
        ->getQuery()
        ->getResult()
    ;
    

    Esto generará una consulta SQL válida que recuperará los datos que necesitas.

    Cabe destacar que el cálculo (e.year * 100 + e.week_number) se repite en ambas cláusulas andWhere, por lo que podrías almacenarlo en una variable para que el código sea más claro:

    $weekNumber = '(e.year * 100 + e.week_number)';
    
    return $this->createQueryBuilder('e')
        ->select('e.user_id', 'e.year', 'e.week_number', 'e.approved_by')
        ->where('e.user_id = :userID')
        ->andWhere("$weekNumber >= :startDate")
        ->andWhere("$weekNumber <= :endDate")
        ->setParameter('userID', $userID)
        ->setParameter('startDate', ($startYear * 100 + $startWeek))
        ->setParameter('endDate', ($endYear * 100 + $endWeek))
        ->getQuery()
        ->getResult()
    ;
    

    Esto facilita la lectura y modificación del código.

Comments are closed.