Symfony 1.4 Doctrine update with inner join - symfony-1.4

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

Related

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();

Convert SQL into Doctrine 2 QueryBuilder

I need help to convert a valid SQL query into createQueryBuilder. The problem I have is I don't know how to LEFT JOIN on a SELECT in the createQueryBuilder.
SELECT username, count(c.user_owner_id) as num_contact, a_g.name as
group_name
FROM `oro_user` as u
INNER JOIN `oro_user_access_group` as u_g on u.id=u_g.user_id
INNER JOIN `oro_access_group` as a_g on u_g.group_id=a_g.id
LEFT JOIN
(SELECT cc.user_owner_id
FROM `orocrm_contact` as cc
INNER JOIN`orocrm_contact_to_contact_grp` as cc_g on cc_g.contact_id=cc.id
INNER JOIN `orocrm_contact_group`
as c_g on cc_g.contact_group_id=c_g.id
WHERE c_g.label='New One' and cc.semester_contacted='2017A')
as c on u.id=c.user_owner_id
WHERE a_g.name='Full-timer' and u.enabled = 1 and u.gender='male'
GROUP BY u.id
ORDER BY num_contact
I have two queries below, I want user to LEFT JOIN the results from contact
$user = $this->em->getRepository('OroUserBundle:User')->createQueryBuilder('u')
->select('u.username')
->innerJoin('u.groups','g')
->andWhere('g.name = :group')
->setParameter('group', 'Full-timer')
->getQuery();
$contacts = $this->em->getRepository('OroContactBundle:Contact')->createQueryBuilder('c')
->select('c')
->innerJoin('c.groups','g')
->andWhere('g.label = :group')
->andWhere('c.semester_contacted = :sem')
->setParameter('group', 'New One')
->setParameter('sem', '2017A')
->setMaxResults(1)
->getQuery();
This is a pretty complex queries and since the ORM QueryBuilder works closer to your entities than the database I'm not sure if you can just "dump" the DQL into a ->join(). The good news with the DBAL QueryBuilder that works:
$dbalQueryBuilder
->from('user_table as u')
...
->join('u', '('.$otherDbalQueryBuilder->getSQL().')', 'c')
This is from memory so it might be a little different, but something like that.
With that you can get all the fields you require, but you won't get any entities. Luckily Doctrine provides ways to build entities from Native SQL using ResultSetMapping.
$userWithContacts = $entityManager->createNativeQuery(
$dbalQueryBuilder->getSQL(),
$yourResultSetMapping
);
I know this is will require more code and is probably not as nice as just using the ORM QueryBuilder, but I find it oftentimes to be the best way to deal with existing queries that need to be ported to ORM somehow.

Complex AX Query

i want to rebuild this SQL Query as AX Query.
I tried it in several ways, but I don't get it.
I am not completely new to AX queries, but I only have experience with some simple queries not with such complex SQL queries.
SELECT * FROM ( SELECT DH.[RECID] AS RECID_DIMENSIONHIERARCHY
,DH.[NAME] AS NAME__DIMENSIONHIERARCHY
,DH.[DESCRIPTION] AS DESC__DIMENSIONHIERARCHY
,DH.[PARTITION] AS PARTITION_DIMENSIONHIERARCHY
,DL.[DIMENSIONATTRIBUTE] AS RECID_DIMENSIONATTRIBUTE
,DA.[NAME] AS NAME_DIMENSIONATTRIBUTE
,DN.[RECID] AS RECID_DIMENSIONCONSTRAINTNODE
,DNC.[RECID] AS RECID_DIMENSIONCONSTRAINTNODECRITERIA
,DNC.[RANGETO] AS #Owner
,DNCR.[WILDCARDSTRING] AS #Agreement
FROM (SELECT * FROM [dbo].[DIMENSIONHIERARCHY]
WHERE [STRUCTURETYPE] = 1 AND [NAME] LIKE 'AG-OW%'
) AS DH
INNER JOIN [dbo].[DIMENSIONHIERARCHYLEVEL] AS DL
ON DH.[RECID] = DL.[DIMENSIONHIERARCHY]
AND DH.[PARTITION] = DL.[PARTITION]
INNER JOIN [dbo].[DIMENSIONATTRIBUTE] AS DA
ON DL.[DIMENSIONATTRIBUTE] = DA.[RECID]
AND DL.[PARTITION] = DA.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODE] AS DN
ON DL.[RECID] = DN.[DIMENSIONHIERARCHYLEVEL]
AND DL.[PARTITION] = DN.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODECRITERIA] AS DNC
ON DN.[RECID] = DNC.[DIMENSIONCONSTRAINTNODE]
AND DN.[PARTITION] = DNC.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODECRITERIA] AS DNCR
ON DN.[PARENTCONSTRAINTNODE] = DNCR.[DIMENSIONCONSTRAINTNODE]
AND DN.[PARTITION] = DNCR.[PARTITION]
) AS Sub
You need to break down your query and implement it in small chunks. Then combine all of it to get the desired result.
There are two ways to create query in X++.
Create query using select statement for example:
Select * from HcmWorker join * from DirPerson
where DirPerson.RecId == HcmWorker.Person
See this link : Select statement syntax
Create query with AOT structure. You might want to have a look at the following link:
Create query in AOT by using X++

How to make JOIN with OR expression in DQL?

Here is the SQL equivalent of what I expect to get from Doctrine:
SELECT c.* FROM comments c
LEFT JOIN articles a
ON a.id = c.articles_id OR a.translation = c.articles_id
WHERE c.published = 1 AND c.language = a.language
The problem is that I cannot make Doctrine to generate the JOIN operation with OR as it is supposed to be. If we execute query from the following QueryBuilder object:
$qb->select('c')
->from('Project:Comment', 'c')
->leftJoin('c.article', 'a', 'WITH', 'a = c.article OR a.translation = c.article')
->where('c.published = true AND c.language = a.language');
we receive the following SQL statement:
SELECT
...
FROM comments c0_
LEFT JOIN articles a0_ ON c0_.articles_id = a0_.id
AND (
a0_.id = c0_.articles_id OR
a0_.translation = c0_.profiles_id
)
WHERE c0_.published = 1 AND c0_.language = a0_.language
which is obviously not the same as the initial query, as WITH operator seems to add additional conditions to the basic one instead of replacing the whole condition.
Is there any way to force Doctrine to output exactly what I need? I know that I may use native SQL but I doubt that it will be as convenient as QueryBuilder. Maybe there is a way to extend Doctrine with normal JOIN ON implementation instead of this odd JOIN WITH?
Doctrine doesn't implement this because it is (as far as I understand at least) not considered optimized enough for SQL.
See this SO post for precisions.
What you intend to do could appearantly be done using Union and other types of Join.

update doctrine with join table

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();

Resources