Symfony2 and DQL - symfony

I'm running this DQL statement:
return $this->getEntityManager()
->createQuery("SELECT s FROM Bundle:table s WHERE s.title LIKE '%:search%'")
->setParameter('search', $search)
->getResult();
But I'm getting this error:
Invalid parameter number: number of bound variables does not match number of tokens
Anyone know what I'm doing wrong?

You cannot use variable substitution like that. Try this:
return $this->getEntityManager()
->createQuery("SELECT s FROM Bundle:table s WHERE s.title LIKE :search")
->setParameter('search', "%" . $search . "%")
->getResult();

Apparently Bundle:table is not a correct reference to a bundle and an entity in your project. Check the spelling and camelCase of your Bundle / entity (or Entity ?) name.

Related

Doctrine get non null ArrayCollection

I would like to get all Entity only if the parameter is part in this entity or if the entity parameter is empty.
I have this:
$qb = $this->createQueryBuilder('cc')
->join('Toblor\Entity\Paramount', 'p')
->select('p')
->Where(':company MEMBER OF p.company_activated')
->setParameter('company ', $company)
return $qb->getQuery()->getResult();
And it is doing to job great. But now I would like to have the same result if company is a part of company_actived OR if company_activated is empty. I have tried an
->Where('(:company MEMBER OF p.company_activated OR p.company_activated IS NULL)')
It trigger me this error
Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
Is there an easy way to do this thing ? Because I need to implement on a lot of fields.
Thanks you
Is your relation with company_activated ManyToMany or OneToMany.
If it's the case, you need to add:
->leftJoin('p.company_activated', 'ca')
then check if ca IS NULL

Symfony2 - Query Builder multiple orderBy

I have the following code
public function queryAssociationsSorted($id){
$qb = $this->createQueryBuilder('a')
->leftJoin('a.category', 'c')
->where('a.job = :id')
->setParameter('id', $id)
//->addOrderBy('c.rank', 'DESC')
//->addOrderBy('a.updated', 'DESC')
->add('orderBy','c.rank DESC THEN a.updated DESC')
;
return $query = $qb->getQuery();
}
and this or the commented out options both only sort by a.updated. I have looked at other posts on this subject and can't find a solution. Can anyone suggest where I am going wrong?
If I understand correctly, and this is the result yu want:
id - rank - updated
xx - 4 - 2014-01-01
xx - 3 - 2014-01-02
xx - 3 - 2014-01-01
This actually works:
$qb = $this->createQueryBuilder('a')
->leftJoin('a.category', 'c')
->where('a.job = :id')
->setParameter('id', $id)
->addOrderBy('c.rank', 'DESC')
->addOrderBy('a.updated', 'DESC')
;
return $query = $qb->getQuery();
I'm not sure how doctrine works with multiple sort by..
why dont you try to use dql or even raw sql query?
http://docs.doctrine-project.org/en/2.1/reference/dql-doctrine-query-language.html
http://doctrine-orm.readthedocs.org/en/latest/reference/native-sql.html
Edit:
something like that will work I think:
->add('orderBy','c.rank DESC, a.updated DESC')
If you still have no success the raw sql query will save you ;)
Over a year later and I've stumbled across the correct answer in this answer by #red777
This will help you:
$adapter = new DoctrineORMAdapter($queryBuilder, false);
Had the same problem this morning. By default Pagerfanta is treating your query as
one with joins. Setting second argument to false makes it use simple
query handling.
In Kunstmaan Bundle, in AdminListConfiguration class, you have to
overide function that is creating Pagerfanta, if you want to sort
simple entity.
The syntax in the query had always been correct, but the error crept in in the DoctrineOrmAdapter. Adding false as the second parameter sorted the problem

Parameters in QueryBuilder (Doctrine/Symfony)

I have this code:
$sort = (is_null($sort)) ? 'i.name' : $sort;
$order = (!is_null($order) && $order == 'ASC') ? 'ASC' : 'DESC';
$queryBuilder
->select('s')
->from('Model:Item', 'i')
->where('i.isRemoved = false')
->orderBy(':sort', $order)
->setParameter('sort', $sort);
But I get this error:
[1/2] QueryException: SELECT i FROM Model:Item i WHERE i.isRemoved = false ORDER BY :sort DESC
I must be doing something wrong with the setParameter() call, but I can't figure out what?
Any ideas? Thanks
setParameter() is used to prevent SQL injection attacks, since many WHERE clauses rely on user input.
And this might be the cause of the problem here -- I'm not entirely sure that the ORDER BY clause supports parameter replacement. I may be wrong on that, but your error seems to indicate that either (1) it doesn't support it, or (2) you're getting bad input.
Where exactly are you getting your $sort from? If it's coming from some user input, then you might want to perform the sanitization logic here instead, and just set the resolved value in the orderBy() method.
Consider an example where id and name are actual fields. What happens when someone tries to pass in i.description? The entire SQL would fail. But not if you did something like this:
$sort = (in_array($sort, array('i.id', 'i.name')))
? $sort
: 'i.name';
// Now you've effectively sanitized the value
// i.e. It's *always* going to be either 'i.id' or 'i.name'
// So there's no reason to need something like setParameter()
$queryBuilder
->select('s')
->from('Model:Item', 'i')
->where('i.isRemoved = false')
->orderBy($sort);

Using wildcards with Doctrine's createQuery method

Can anyone enlighten me as to why this query isn't working please? I tried alternating between single and double quotes as well.
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery('SELECT t FROM AcmeBlogBundle:BlogTag t WHERE t.title LIKE \'%:title%\'')
->setParameter('title', $keyword);
Doctrine simply returns Invalid parameter number: number of bound variables does not match number of tokens.
Also, is it better to perform such a query using the createQuery method or createQueryBuilder?
PDO treats both the keyword and the % wildcards as a single token. You cannot add the wildcards next to the placeholder. You must append them to the string when you bind the params.
Also see this comment on the php docs.
Therefore you will need to do the following:
$qb = $em->createQueryBuilder();
$qb
->select('tag')
->from('AcmeBlogBundle:BlogTag', 'tag')
->where($qb->expr()->like('tag.title', ':title'))
->setParameter('title', '%' . $keyword . '%')
;
or
$query = $em->createQuery('SELECT t FROM AcmeBlogBundle:BlogTag t WHERE t.title LIKE :title');
$query->setParameter('title', '%' . $keyword . '%');
I prefer to use the query builder because it is nicer for structuring and making your statement more maintainable

How to use wildcards in createQueryBuilder?

In my repository class i use:
public function getItemsByTag($tag)
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where('c.tags LIKE %bipolar%')
->addOrderBy('c.id');
return $qb->getQuery()
->getResult();
}
But unfortunately this doesn't work.. Anybody knows how this can work? Or do I have to build a custom query without the QueryBuilder?
Thanks!
Searching based on a single parameter:
I think it should go:
public function getItemsByTag($tag)
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where('c.tags LIKE :tag')
->addOrderBy('c.id')
->setParameter('tag', $tag);
return $qb->getQuery()->getResult();
}
But I think that it is discouraged to do a LIKE as part of a where using the query builder so you should do:
$qb = $this->createQueryBuilder('c');
$qb->select('c')
->where($qb->expr()->like('c.tags', '?1'))
->addOrderBy('c.id')
->setParameter(1, $tag);
return $qb->getQuery()->getResult();
Check out the docs for more information, there is an example of a like expression in the section entitled Helper Methods
I should also point out that I used a different convention in each example for passing a parameter into a query, the first used a named parameter :tag which is set by setParameter('tag', $value) the second is just a numbered parameter ?1, you could have just as easily have used a named parameter in the second example if you wished to as well.
Searching with an array of parameters:
You also asked about doing an array of likes. Here it is with an OR expression but if you wanted to search for all tags you could change it to an AND.
In order to make a "LIKE array" you just have to build up the expression on its own.
$qb = $this->createQueryBuilder('c');
$orExpr = $qb->expr()->orX();
for ($i = 0; $i < count($tags); $i++) {
$orExpr->add($qb->expr->like('c.tags', "?$i"));
// You may have to set params later in a loop after $orExpr has been
// added to the queryBuilder.
$qb->setParameter($i, $tags[$i]);
}
$qb->select('c')->where($orExpr)->addOrderBy('c.id');
return $qb->getQuery()->getResult();
If you don't want to substitute your query with variables but use a static string you have to put the string in apostrophes.
You have to use apostrophes instead of quotes! Otherwise the Doctrine2 Lexer will throw an Exception.
So in your case Mike you can use:
'c.tags LIKE \'%bipolar%\''
or
"c.tags like '%bipolar%'"
I don't know much about Symfony, but based on what I know about PHP and MySQL, I imagine you mean 'c.tags LIKE "%bipolar%"'. You likely need quotation marks around %bipolar%.
simply:
public function getItemsByTag($tag)
{
$qb = $this->createQueryBuilder('c')
->select('c')
->where( $qb->expr()->like('c.tags', ':tags') )
->addOrderBy('c.id');
$qb->setParameter('tags', '%' . $tag . '%' );
return $qb->getQuery()->getResult();
}

Resources