update doctrine with join table - symfony

I am trying to update the field "note" in Note Entity which have a relation ManyToOne (bidirectionnel) with "ElementModule" and "Inscription", the entity "Inscription" have a relation ManyToOne with the "Etudiant" Entity
I tried this DQL Query:
$query = $this->_em->createQuery('update UaePortailBundle:Note u JOIN u.inscription i JOIN u.elementmodule e join i.etudiant et set u.note = ?3
where et.id = ?1 and e.id = ?2 ');
$query->setParameter(1, $etudiant);
$query->setParameter(2, $element);
$query->setParameter(3, $note);
$resultat = $query->execute();
i get this error
[Syntax Error] line 0, col 50: Error: Expected Doctrine\ORM\Query\Lexer::T_EQUALS, got 'i'

LEFT JOIN, or JOINs in particular are only supported in UPDATE statements of MySQL. DQL abstracts a subset of common ansi sql, so this is not possible. Try with a subselect or IDENTITY ( you must use the latest version of Doctrine 2.2.2 ) :
createQuery('update UaePortailBundle:Note u set u.note = ?3
where IDNETITY(u.inscription) = ?1 and IDENTITY(u.elementmodule) = ?2 ');

after searching and trying to find a solution for that using doctrine dql, i was not able to find it, so i used direct sql query to update the database.
$stmt = $this->getEntityManager()
->getConnection()
->prepare("update note set note = :note where `etudiant_id` like :etudiant_id and `elementmodule_id` like :elementmodule_id");
$stmt->bindValue('etudiant_id',$etudiant);
$stmt->bindValue('elementmodule_id' ,$element );
$stmt->bindValue('note', $note);
$stmt->execute();

Related

Need help for performing join Query with QueryBuilder

I got a working SQL query : select p.name, p.id from acv_project p join acv_product prod on prod.project_id = p.id where prod.weight <> 0 and p.green_user_id = 18
If i pass it into a `
$stmt = $em->getConnection()->prepare($rawSql);
$stmt->execute([]);
$projects = $stmt->fetchAll();
It works but i'd like to pass it by adding the "green_user_id" as a parameter and not always 18.
When i try with this code : `
$sql2 = "select p from ArtoAcvBundle:Project p join prod ArtoAcvBundle:Product on prod.project_id = p.id where prod.weight <> 0 and p.green_user_id =:userId";
$query2 = $em->createQuery($sql2)->setParameters(
array('userId' => $userId));
$projects = $query2->getResult();
I get [Semantical Error] line 0, col 48 near 'ArtoAcvBundle:Product': Error: Identification Variable prod used in join path expression but was not defined before.
And with QueryBuilder, i tried lots of thing but fails to understand how to write it.
Here are some links to my 2 Doctrine entities :
Entity Product
Entity Project
Thanks for help !
Proof with:
$sql2 = "select p from ArtoAcvBundle:Project p join ArtoAcvBundle:Product prod where prod.weight <> 0 and p.green_user_id =:userId";
Yep, great thanks for having found this solution. I continued to search and find there existed a bindValue() method in Doctrine.
So i passed my parameter with the raw SQL modified and it works
Example with QueryBuilder
// select p from ArtoAcvBundle:Project p join prod ArtoAcvBundle:Product on prod.project_id = p.id where prod.weight <> 0 and p.green_user_id =:userId
$query = $this->getRepository(Project::class)->createQueryBuilder('p');
$query->join('p.products' , 'prod')
->andWhere('prod.weight <> 0')
->andWhere('p.greenUser = :user')
->addParameter('user', $youruserEntity);
return $query->getQuery()->getResult();

Doctrine Native query inside query builder join

I am working on a query on Doctrine 2 (with Symfony 2.8)
I have this query giving me relevant info:
$qb = $this->createQueryBuilder('ea');
$qb->join('ea.entity_b', 'eb')
->join('ea.entity_c', 'ec')
->join('ec.entity_d', 'ed')
->join('MainBundle:Entity_E', 'ee','WITH', 'ee.column1 = ea.id')
->join('MainBundle:Entity_F', 'ef', 'WITH', 'ea.column1 = ef.id');
Now, I need to add extra info to that query, but it comes from a native SQL, something like this:
SELECT * FROM DS ORDER BY id DESC LIMIT 1
And make sure that the id of the result from the native query is equal to ef.id
I hope I made any sense.
Thanks
Do you know DQL ?
Similar to SQL but adapted for Doctrine.
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html
You can then do queries like :
<?php
$query = $em->createQuery("SELECT u FROM User u JOIN u.address a WHERE a.city = 'Berlin'");
$users = $query->getResult();

Symfony 1.4 Doctrine update with inner join

I'm going to write MySQL query like follow query in doctrine.
UPDATE vehicle a
INNER JOIN vehicle b ON a.id = b.id
SET a.total_view = b.total_view+1
WHERE a.id=1;
I tried in doctrine like follow. But it doesn't work.
Is there any solution for that ?
$q = Doctrine_Query::create()
->update('Vehicle v')
->innerJoin('v.Vehicle v2')
->set('v.total_view = v2.total_view+1')
->where('v.id = ?',$id);
return $q->execute();
From what I recall in a past project, you just can't because it is not supported. You have to do it manually with native sql like this
Resources:
http://www.doctrine-project.org/jira/browse/DC-202
https://groups.google.com/forum/#!topic/doctrine-user/H0-EcZXyrek

Semantical Error - Doctrine 2.0

These are my tables:
Table Gift:
-id
-price
...
Table Couple:
-id
-name
...
table registry: //provide a many-many relation between gifts and couples
-id
-coupleId
-giftId
table purchase:
-amount
-registryId
I already wrote a sql query to get all the gift info for a specific couple
$qb = $this->createQueryBuilder('g') //gift
->from('\BBB\GiftBundle\Entity\Registry', 'reg')
->select('g.id , g.price')
->where('reg.gift = g.id')
->andWhere('reg.couple = :coupleID')
->orderBy('reg.id','DESC')
->setParameter('coupleID', $coupleID);
OR
SELECT g.id , g.price,
FROM gift g, registry reg
WHERE reg.gift_id = g.id AND reg.couple_id = 1
I also want to get the total amount that for the gifts that have been bought (if any)
EX. SUM(purchase.amount) as totalContribute
I have tried:
$qb = $this->createQueryBuilder('g')
->from('\BBB\GiftBundle\Entity\Purchase', 'p')
->from('\BBB\GiftBundle\Entity\Registry', 'reg')
->select('g.id , g.price')
->addSelect('SUM(p.amount) as totalContribute')
->leftJoin('p','pp', 'ON','reg.id = pp.registry')
->where('reg.gift = g.id')
->andWhere('reg.couple = :coupleID')
->orderBy('reg.id','DESC')
->setParameter('coupleID', $coupleID);
but it gives me the following error:
[Semantical Error] line 0, col 145 near 'pp ON reg.id': Error: Identification Variable p used in join path expression but was not defined before.
First of all, you should define join condition in your SQL statements after joins, not in WHERE clause. The reason is that it's really not efficient. So the query shoul look like:
SELECT g.id , g.price,
FROM gift g JOIN registry reg ON reg.gift_id = g.id
WHERE reg.couple_id = 1
But about your Doctrine query, You get error because you're defining joins in wrong way. Your query should more like:
$qb = $this->createQueryBuilder('g') // You don't have put "from" beacuse I assume you put this into GiftRepository and then Doctrine knows that should be \BBB\GiftBundle\Entity\Gift
->select('g.id , g.price')
->addSelect('SUM(p.amount) as totalContribute')
->join('g.purchase','p') // pay attention for this line: you specify relation basing on entity property - I assume that is "$purchase" for this example
->leftJoin('p.registry', 'reg') // here you join with \BBB\GiftBundle\Entity\Purchase
->where('reg.couple = :coupleID')
->orderBy('reg.id','DESC')
->setParameter('coupleID', $coupleID);
Please treat this as pseudocode - I didn't check it works but it should like more like this.
One more thing - if your repository method returns object(s) of X entity you should put this method to XRepository.

Symfony2 Doctrine SQL object mapping on subselect

I'm trying to use this query:
MySQL SELECT DISTINCT by highest value
SELECT
p.*
FROM
product p
INNER JOIN
( SELECT
magazine, MAX(onSale) AS latest
FROM
product
GROUP BY
magazine
) AS groupedp
ON groupedp.magazine = p.magazine
AND groupedp.latest = p.onSale ;
Within Symfony2 and DQL.
I have:
$query = $em->createQuery("SELECT p FROM MyBundle:Product p WHERE p.type = 'magazine' AND p.maglink IS NOT NULL OR (p.type = 'magazine' AND p.diglink IS NOT NULL) GROUP BY p.magazine ORDER BY p.onSale DESC");
Which works fine with and outputs objects but without the correct MAX(onSale)
Doing:
$query = $em->createQuery("SELECT p , MAX(p.onSale) FROM MyBundle:Product p WHERE p.type = 'magazine' AND p.maglink IS NOT NULL OR (p.type = 'magazine' AND p.diglink IS NOT NULL) GROUP BY p.magazine ORDER BY p.onSale DESC");
Results in non-objects being returned.
This:
$query = $em->createQuery("SELECT
p.*
FROM
MyBundle:Product p
INNER JOIN
( SELECT
p.magazine, MAX(onSale) AS p.latest
FROM
MyBundle:Product p
GROUP BY
p.magazine
) AS groupedp
ON groupedp.magazine = p.magazine
AND groupedp.latest = p.onSale ;");
Throws this error:
[Semantical Error] line 0, col 127 near 'SELECT
': Error: Identification Variable ( used in join path expression but was not defined before.
I assume due to this Symfony2 Doctrine query
How can I maintain my mapping while still being able to sort each item by onsale?
Have you considered splitting this into two queries:
First:
Run your query directly against the database connection, and return the IDs of the relevant rows, in the order you want. This separates your complex query from DQL.
Second:
Query the rows through Doctrine to get the full entities you want, based on the IDs/orders of the previous query.
This is a shot in the dark, but it seems fairly obvious. Your aliasing two tables to the same alias. Thus when your using p. in the join it thinks your working from the original definition of p from before the join, then you alias the join as p. Change the alias of the join (and the references to that table) so each alias is unique.

Resources