HOW MAKE A update WITH left join DOCTRINE - symfony

i want to do this in doctrine symonfy2
update producto p
left join producto_compra pc ON p.id = pc.id_producto
set p.cantidad = (p.cantidad - pc.cantidad)
where pc.id_compra = '56';
and i tried with this, and it doesnt work
$em = $this->getEntityManager();
$query = $em->createQuery('UPDATE ORM\Entity\Producto p '
. 'LEFT JOIN ORM\Entity\ProductoCompra pc WITH p.id = pc.idProducto '
. 'SET p.cantidad = (p.cantidad - pc.cantidad) '
. 'WHERE pc.idCompra = :fc ')
->setParameter('fc', $facturacompra);

similar question look at here, i see that join is not supported in update or delete queries.

Related

Operator "NOT LIKE" not work correctly

i am creating a new query in my app.
I use filters, with different options (Contain, equal or different).
If I use operator "different", my query generate like this:
SELECT p FROM ProductosBundle:Producto p
LEFT JOIN p.tipo t
LEFT JOIN p.departamento d
WHERE 1=1 AND t.nombre NOT LIKE '%articulo%'
I have product different from "articulo", but return 0 results...
I tried with NOT LIKE, != and <>, but not return results.
Is there something wrong in my condition where? I do not see the problem, with contain and equal it works.
Any idea? Thanks
EDIT 1:
This is my controller:
...
$em = $this->get('doctrine.orm.entity_manager');
$dql = "SELECT p FROM ProductosBundle:Producto p LEFT JOIN p.tipo t LEFT JOIN p.departamento d";
if (isset($_GET['filterField']) && isset($_GET['filterValue'])){
$valores = explode(",",$_GET['filterValue']);
$filas = explode(",",$_GET['filterField']);
$operadores = explode(",",$_GET['filterOperator']);
$dql .= " WHERE 1=1";
for($i = 0; $i < count($valores); $i++){
$dql.= " AND ". $filas[$i]. " " . $operadores[$i] ;
if($operadores[$i] == "LIKE" OR $operadores[$i] == "NOT LIKE"){
$dql .= " '%".$valores[$i]."%'";
}else{
$dql .= " '".$valores[$i]."'";
}
}
}
$query = $em->createQuery($dql);
$paginator = $this->get('knp_paginator');
$productos = $paginator->paginate(
$query,
$request->query->get('page', 1),
25
);
EDIT2:
My profiler is executing this:
SELECT DISTINCT p0_.id AS id_0
FROM producto p0_
LEFT JOIN tipo t1_ ON p0_.tipo = t1_.id
LEFT JOIN departamento d2_ ON p0_.departamento = d2_.id
WHERE t1_.nombre LIKE 'articulo'
AND 1 = 1
AND t1_.nombre NOT LIKE '%articulo%'
LIMIT 25 OFFSET 0
Its a LIKE 'Articulo'... WHY???!!!
Presumably, there's an error in your UI logic / the code setting the query parameters. This:
$valores = explode(",",$_GET['filterValue']);
$filas = explode(",",$_GET['filterField']);
$operadores = explode(",",$_GET['filterOperator']);
generates both
t1_.nombre LIKE 'articulo'
and
t1_.nombre NOT LIKE '%articulo%'
so you should take a look at the code that populates filterValue, filterField and filterOperator.

Semantical Error, Symfony DQL

I have a query that perform normally with MySQL :
SELECT *
FROM td_user u
JOIN td_ranking ranking ON ranking.user_id = u.id
JOIN (
SELECT x.user_id,
MAX(x.id) AS default_id
FROM td_ranking x
GROUP BY x.user_id
) y
ON y.user_id = ranking.user_id
AND y.default_id = ranking.id
I try to transform it in DQL for run it in Symfony :
$query = $this->_em->createQuery('
SELECT u.*,ranking.*
FROM UserBundle:User u
JOIN UserBundle:Ranking ranking
WITH ranking.user_id = u.id
JOIN (
SELECT x.user_id, MAX(x.id) AS default_id
FROM UserBundle:Ranking x
GROUP BY x.user_id
) y
ON y.user_id = ranking.user_id
AND y.default_id = ranking.id'
);
$results = $query->getResult();
I have this error :
[Semantical Error] line 0, col 113 near '(SELECT x.user_id,': Error: Class '(' is not defined.
Do you have any idea please ? Thanks!
Use native query
$rsm = new ResultSetMapping();
$sql = "
SELECT *
FROM td_user u
JOIN td_ranking ranking ON ranking.user_id = u.id
JOIN (
SELECT x.user_id,
MAX(x.id) AS default_id
FROM td_ranking x
GROUP BY x.user_id
) y
ON y.user_id = ranking.user_id
AND y.default_id = ranking.id
";
$result = $this->getEntityManager()->createNativeQuery($sql, $rsm)->getResult();

doctrine in combination with TranslationWalker generates too many queries

I have multilingual project and I use symfony2+doctrine.
If I try to display list of objects in language different than the default one, doctrine generates one query to get all data for all objects and then generates one query for every single object, witch is unnecessary.
The code in the repository code looks like:
$repository = $this->_em->getRepository($this->_entityName);
$keywordController = new \Cms\Bundles\KeywordBundle\Controller\ObjectKeywordController();
$queryBuilder = $repository->createQueryBuilder('e');
$queryBuilder->andWhere('e.status=:status');
$queryBuilder->setParameter('status', 'public');
$queryBuilder->andWhere('e.displayTranslation = :displayTranslation');
$queryBuilder->setParameter('displayTranslation', 'true');
$queryBuilder->orderBy('e.publishedDate', 'DESC');
$query = $queryBuilder->getQuery();
$query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker');
if ($locale) {
$query->setHint(\Gedmo\Translatable\TranslatableListener::HINT_TRANSLATABLE_LOCALE, $locale);
}
$paginator = new Paginator($query);
$total_items = count($paginator);
$pages_count = (int) ceil($total_items / $page_row_count);
// now get one page's items:
$paginator
->getQuery()
->setFirstResult($page_row_count * ($current_page - 1)) // set the offset
->setMaxResults($page_row_count); // set the limit
I and get the following queries:
SELECT a0_.id AS id_0, t1_.content AS title_1, t2_.content AS sub_title_2, t3_.content AS announce_3, t4_.content AS author_4, t5_.content AS content_5, t6_.content AS source_6, a0_.creation_date AS creation_date_7, a0_.update_date AS update_date_8, a0_.published_date AS published_date_9, a0_.schedule_disable_date AS schedule_disable_date_10, a0_.schedule_publish_date AS schedule_publish_date_11, t7_.content AS seo_title_12, t8_.content AS seo_description_13, t9_.content AS keywords_as_text_14, t10_.content AS main_pic_description_15, t11_.content AS main_pic_title_16, t12_.content AS slug_17, t13_.content AS status_18, t14_.content AS display_translation_19, a0_.comments_enabled AS comments_enabled_20, t15_.content AS comments_count_21, a0_.main_pic AS main_pic_22, a0_.poll_id AS poll_id_23, a0_.attachment_id AS attachment_id_24, a0_.gallery_id AS gallery_id_25, a0_.created_by AS created_by_26, a0_.main_category_id AS main_category_id_27 FROM articles a0_ LEFT JOIN article_translations t1_ ON t1_.locale = 'bg' AND t1_.field = 'title' AND t1_.object_id = a0_.id LEFT JOIN article_translations t2_ ON t2_.locale = 'bg' AND t2_.field = 'subTitle' AND t2_.object_id = a0_.id LEFT JOIN article_translations t3_ ON t3_.locale = 'bg' AND t3_.field = 'announce' AND t3_.object_id = a0_.id LEFT JOIN article_translations t4_ ON t4_.locale = 'bg' AND t4_.field = 'author' AND t4_.object_id = a0_.id LEFT JOIN article_translations t5_ ON t5_.locale = 'bg' AND t5_.field = 'content' AND t5_.object_id = a0_.id LEFT JOIN article_translations t6_ ON t6_.locale = 'bg' AND t6_.field = 'source' AND t6_.object_id = a0_.id LEFT JOIN article_translations t7_ ON t7_.locale = 'bg' AND t7_.field = 'seoTitle' AND t7_.object_id = a0_.id LEFT JOIN article_translations t8_ ON t8_.locale = 'bg' AND t8_.field = 'seoDescription' AND t8_.object_id = a0_.id LEFT JOIN article_translations t9_ ON t9_.locale = 'bg' AND t9_.field = 'keywordsAsText' AND t9_.object_id = a0_.id LEFT JOIN article_translations t10_ ON t10_.locale = 'bg' AND t10_.field = 'mainPicDescription' AND t10_.object_id = a0_.id LEFT JOIN article_translations t11_ ON t11_.locale = 'bg' AND t11_.field = 'mainPicTitle' AND t11_.object_id = a0_.id LEFT JOIN article_translations t12_ ON t12_.locale = 'bg' AND t12_.field = 'slug' AND t12_.object_id = a0_.id LEFT JOIN article_translations t13_ ON t13_.locale = 'bg' AND t13_.field = 'status' AND t13_.object_id = a0_.id LEFT JOIN article_translations t14_ ON t14_.locale = 'bg' AND t14_.field = 'displayTranslation' AND t14_.object_id = a0_.id LEFT JOIN article_translations t15_ ON t15_.locale = 'bg' AND t15_.field = 'commentsCount' AND t15_.object_id = a0_.id WHERE t13_.content = 'public' AND t14_.content = 'true' AND a0_.id IN ('176448', '176447', '176446', '176444', '176442', '176441', '176440', '176437', '176436', '176435', '176434', '176424') ORDER BY a0_.published_date DESC;
and the for every object a query like:
SELECT t0.id AS id_1, t0.locale AS locale_2, t0.field AS field_3, t0.content AS content_4, t0.object_id AS object_id_5 FROM article_translations t0 WHERE t0.object_id = ?
How to avoid this extra queries and why doctrine don't use the data from the first one?
Note: All extra queries are generated in function postLoad in the TranslatableListener class. There is a parameter $skipOnLoad, which is always false, and it looks like this is somehow the problem, but why this happens I have no idea:)

Subquery's with limit in Doctrine/Symfony using DQL

I would like to know how can I set limit on 1 query and then query based on the selected results.
For example I want to select the last 100 posts and the do some operation.
$first_query= $this->getEntityManager()
->createQuery(
'SELECT p FROM TestBundle:Post p ORDER BY p.date DESC'
)
->setMaxResults(5);
How to use this result to select from it in the next query?
return $this->getEntityManager()
->createQuery(
"SELECT u.username , max(p.date),d.points,l.name
FROM $first_query
JOIN p.location l JOIN p.user u JOIN u.deeds d
WHERE l.name = :location
GROUP BY u.id
ORDER BY d.points DESC , p.date DESC
"
)
->setParameter('location' , $location)
->getResult();
I found out that DQL doesn't support limits so I went for native sql.
$stmt = $this->getEntityManager()->getConnection()->prepare($query);
$stmt->execute();
return $stmt->fetchAll();
This way you can do whatever you want with the $query varaible you can set limits and everythign as it's a normal sql statement.

innerjoin query in drupal 7

I am applying this query for below D6 query , not working ..dont know wat wrong i'm doing ....does innerjoin fails in some condition
$result = db_select('px_slides','s')
->join('node','n','s.vid = n.vid')
->fields('s',array('tissue_type','body_site'))
->fields('n',array('sticky','title'))
->condition('n.status','1','=')
->condition('s.cid','126','=')
->execute()->fetchObject();
drupal 6 query i have:
$result = db_query('
SELECT n.nid, n.vid, n.sticky, n.title, n.created, s.cid, s.ref_id, s.viewurl, s.specimen_type, s.tissue_type, s.body_site, s.test_type, s.algorithm, s.result
FROM {px_slides} s INNER JOIN {node} n ON n.vid = s.vid
WHERE n.status = 1 ')->execute();
You need to put your call to ->join() on a separate line altogether, as it doesn't return the query object:
$query = db_select('px_slides','s')
->fields('s',array('tissue_type','body_site'))
->fields('n',array('sticky','title'))
->condition('n.status','1','=')
->condition('s.cid','126','=');
$query->join('node','n','s.vid = n.vid');
$result = $query->execute()->fetchObject();
The join method does not chain like that. You will have to do something like:
$query = db_select('px_slides','s')
->join('node','n','s.vid = n.vid');
$query->fields('s',array('tissue_type','body_site'))
->fields('n',array('sticky','title'))
->condition('n.status','1','=')
->condition('s.cid','126','=');
$result = $query->execute()->fetchObject();
Also you can use the to string magic method to see the query it is going to execute.
$query->__toString();
Try this...
$query = db_select('px_slides', 's');
$query->innerJoin('node,'n','s.vid = n.vid');
$query->fields('s',array('tissue_type','body_site'));
$query->fields('n',array('sticky','title'));
$query->condition('n.status','1');
$query->condition('s.cid','126');
$result= $query->execute()->fetchAll(PDO::FETCH_ASSOC);

Resources