Symfony2 doctrine DQL does not replace wildcards - symfony

I'm trying to query the model from my Symfony2 project and I am not able to replace wildcards into my DQL query. Look;
$q2 =
'SELECT
p.codigo,
p.descripcion,
SUM(l.cantidad) as cantidad,
SUM(l.cantidad*l.pvp) as euros
FROM
MGFAppBundle:LineaVenta l
JOIN
MGFAppBundle:Producto p
WITH
l.producto = p.id
JOIN
l.venta v
WITH
l.venta = v.id
WHERE
l.producto IN (:array)
AND
v.farmacia = :farmacia
GROUP BY
p.codigo';
$query2 = $this->em->createQuery($q2)
->setParameter('farmacia', $farmacia)->setParameter('array', $array);
$porFarmacia = $query2->getResult();
// This does not return a single value, when it should return 2 lines.
echo $query2->getSQL();
// Returns:
// SELECT p0_.codigo AS codigo0, p0_.descripcion AS descripcion1, SUM(l1_.cantidad) AS sclr2, SUM(l1_.cantidad * l1_.pvp) AS sclr3 FROM LineaVenta l1_ INNER JOIN Producto p0_ ON (l1_.lineaventas_id = p0_.id) INNER JOIN Venta v2_ ON l1_.venta_id = v2_.id AND (l1_.venta_id = v2_.id) WHERE l1_.lineaventas_id IN (?) AND v2_.farmacia_id = ? GROUP BY p0_.codigo
So, question marks where parameters should be. Any hint? Thanks in advance.

Related

DQL request from = to IN

I have an issue with the IN instruction for a field...maybe you can see better than me what's happening.
The issue is on the waves parameter.
I got this in my database it's a configuration field...and this field contain a json
{
"typeId":"10,57",
"codeVague":"ITM1702A,ITMTEST"
}
This request inside sql return results:
SELECT v.id,v.`vague_code`, v.`date_fin_ultime`,m.*
FROM Vague v
INNER JOIN Enquete e ON e.`vague_id` = v.`id`
INNER JOIN Mission m ON m.id = e.`mission_id`
INNER JOIN Contrat c ON c.id = m.`contrat_id`
INNER JOIN `User` u ON u.`enqueteur_id` = e.`enqueteur_id`
INNER JOIN `PointDeVente` p ON p.id = e.`pdv_id`
WHERE v.`vague_code` IN ('ITM1702A','ITMTEST')
AND type_id IN (10,57)
But when I try to do the same from my symfony controller...I got an empty result
$sql="SELECT v.id,v.codeVague, v.date_fin_ultime,c.distance,p.adresse1,p.code_postal,p.ville,m
FROM McInvestigatorBundle:Vague v
INNER JOIN McInvestigatorBundle:Enquete e WITH e.vague_id = v.id
INNER JOIN McInvestigatorBundle:Mission m WITH m.id = e.mission_id
INNER JOIN McInvestigatorBundle:Contrat c WITH c.id = m.contrat
INNER JOIN McInvestigatorBundle:User u WITH u.enqueteur_id = e.enqueteur_id
INNER JOIN McInvestigatorBundle:PointDeVente p WITH p.id = e.pdv_id
WHERE v.codeVague IN (:waves)
AND e.type_id IN (:type_id)
AND m.enqueteur_id=:enq_id
ORDER BY m.date_rea_prev ASC";
$results= $em->createQuery($sql)->setParameters([
'waves' => $waves,
'type_id' => $type_id,
'enq_id' => $enq_id,
])->getResult();
The strange thing is that I got no issue with type_id, it works fine.
But, the waves field it's not the same story....
In fact, it works only if I have only one value in the json
"codeVague":"ITM1702A" is working
"codeVague":"ITM1702A,ITMTEST" is not working.
I already tried those strings in $waves.
"ITM1702A,ITMTEST" and "'ITM1702A','ITMTEST'" and "'ITM1702A,ITMTEST'"
Thanks you for your help !
EDIT: Problem solved, thanks Veve.

Limit the subquery results in DQL

I want to use LIMIT 1 clausule on the subquery in SELECT in DQL query...How can I do that?
"SELECT partial p.{productId, productName, count, price, utwTs},
(
SELECT pp.fileName
FROM AdminBundle:ProductPhoto pp
WHERE pp.productId = p.productId
// LIMIT 1 <--- here
) AS photo_name,
u.avatarName
FROM AdminBundle\Entity\Product p
LEFT JOIN AdminBundle\Entity\Users u WITH u.id = p.userId
LEFT JOIN AdminBundle\Entity\Shop sh WITH sh.userId = u.id
LEFT JOIN AdminBundle\Entity\Stand s WITH p.standId = s.standId
WHERE p.active = 1 and p.productId > 0";
How can I do this? I can't use native sql, becuase pagination (knpbundle) won't work.
That's not possible for security reasons ...
see this -> http://www.doctrine-project.org/jira/browse/DDC-885
eventually you can still make you subquery into a query and limit results with ->setMaxResults( XX ) , et use it into your main query.

DQL - leftJoin() error: Expected Literal, got 'JOIN'

This code:
$builder->select('p')
->from('ProProposalBundle:Proposal', 'p')
->leftJoin('ProProposalBundle:Proposal:Vote', 'v')
->leftJoin('ProUserBundle:User', 'u')
->andWhere('v.proposal = p')
->andWhere('v.user = u')
->andWhere('v.decision = "in_favor" OR v.decision = "against"')
->andWhere('u = :user')
->setParameter('user', $options['user'])
->andWhere('p.community = :community')
->setParameter('community', $community)
->andWhere('p.archived = :archived')
->setParameter('archived', $options['archived'])
->leftJoin('p.convocation', 'c')
->andWhere("p.convocation IS NULL OR c.status = '" . Convocation::STATUS_PENDING . "'");
return $builder->getQuery()->execute();
is returning an error:
[Syntax Error] line 0, col 106: Error: Expected Literal, got 'JOIN'
This is the formed query:
SELECT p FROM ProProposalBundle:Proposal p LEFT JOIN ProProposalBundle:Proposal:Vote v LEFT JOIN ProUserBundle:User u LEFT JOIN p.convocation c WHERE v.proposal = p AND v.user = u AND (v.decision = "in_favor" OR v.decision = "against") AND u = :user AND p.community = :community AND (p.convocation IS NULL OR c.status = 'pending') ORDER BY p.created desc
LEFT JOIN is missing the ON or WITH condition. The question is: what am I doing wrong with DQL query? Am I wrong with leftJoin() method?
Doctrine ORM needs you to tell which relation is joined, not the entity itself (you did it well with p.convocation) :
$builder->select('p')
->from('ProProposalBundle:Proposal', 'p')
->leftJoin('ProProposalBundle:Proposal\Vote', 'v', 'WITH', 'v.proposal = p AND v.user = :user AND (v.decision = :in_favor OR v.decision = :against)')
->setParameter('user', $options['user'])
->setParameter('in_favor', 'in_favor')
->setParameter('against', 'against')
->andWhere('p.community = :community')
->setParameter('community', $community)
->andWhere('p.archived = :archived')
->setParameter('archived', $options['archived'])
->leftJoin('p.convocation', 'c')
->andWhere("p.convocation IS NULL OR c.status = :pending")
->setParameter('pending', Convocation::STATUS_PENDING);
return $builder->getQuery()->execute();
edit: I inversed Vote relation as you commented and removed useless WHERE clauses (Doctrine automatically resolves JOIN ON clause. I also transferred some WHERE clauses about joins in the optional params (WITH in DQL).
edit2: Without relation between Proposal and Vote, not sure it works.
edit3: Best practice is to use setParameter for all values in WHERE clauses.

Drupal db_select(), how can I use two db field in condition?

I have a problem with a drupal db_select.
Here is my code :
$query = db_select('node', 'n');
$query->addField('n', 'nid', 'nid');
$query->addField('cfs', 'entity_id', 'feature_support_id');
$query->addField('fpffs', 'entity_id', 'parent_feature_support_id');
$query->addField('cfsfc', 'feature_support_compared_target_id', 'feature_support_compared');
$query->addField('fpffsfc', 'feature_support_compared_target_id', 'parent_feature_support_compared');
//Get feature_support of the feature
$query->join('field_data_feature_support_feature', 'cfs', 'n.nid = cfs.feature_support_feature_target_id');
$query->join('field_data_feature_support_compared', 'cfsfc', 'cfs.entity_id = cfsfc.entity_id');
//Get parent feature_support through feature
$query->join('field_data_feature_parent_feature', 'fp', 'n.nid = fp.entity_id');
$query->join('field_data_feature_support_feature', 'fpffs', 'fp.feature_parent_feature_target_id = fpffs.feature_support_feature_target_id');
$query->join('field_data_feature_support_compared', 'fpffsfc', 'fpffs.entity_id = fpffsfc.entity_id');
$query->condition('n.nid', $node_revision->nid, '=');
$query->condition('cfsfc.feature_support_compared_target_id', 'fpffsfc.feature_support_compared_target_id', '=');
$result = $query->execute();
In DB my request should be
SELECT n.nid AS nid, cfs.entity_id AS feature_support_id, fpffs.entity_id AS parent_feature_support_id, cfsfc.feature_support_compared_target_id AS feature_support_compared, fpffsfc.feature_support_compared_target_id AS parent_feature_support_compared
FROM node n
INNER JOIN field_data_feature_support_feature cfs ON n.nid = cfs.feature_support_feature_target_id
INNER JOIN field_data_feature_support_compared cfsfc ON cfs.entity_id = cfsfc.entity_id
INNER JOIN field_data_feature_parent_feature fp ON n.nid = fp.entity_id
INNER JOIN field_data_feature_support_feature fpffs ON fp.feature_parent_feature_target_id = fpffs.feature_support_feature_target_id
INNER JOIN field_data_feature_support_compared fpffsfc ON fpffs.entity_id = fpffsfc.entity_id
WHERE (n.nid = '9') AND (cfsfc.feature_support_compared_target_id = fpffsfc.feature_support_compared_target_id)
This request work when I try it in phpmyadmin, but instead in mysql log I have
SELECT n.nid AS nid, cfs.entity_id AS feature_support_id, fpffs.entity_id AS parent_feature_support_id, cfsfc.feature_support_compared_target_id AS feature_support_compared, fpffsfc.feature_support_compared_target_id AS parent_feature_support_compared
FROM node n
INNER JOIN field_data_feature_support_feature cfs ON n.nid = cfs.feature_support_feature_target_id
INNER JOIN field_data_feature_support_compared cfsfc ON cfs.entity_id = cfsfc.entity_id
INNER JOIN field_data_feature_parent_feature fp ON n.nid = fp.entity_id
INNER JOIN field_data_feature_support_feature fpffs ON fp.feature_parent_feature_target_id = fpffs.feature_support_feature_target_id
INNER JOIN field_data_feature_support_compared fpffsfc ON fpffs.entity_id = fpffsfc.entity_id
WHERE (n.nid = '9') AND (cfsfc.feature_support_compared_target_id = 'fpffsfc.feature_support_compared_target_id')
See at the end, in the WHERE, there is single quote around 'fpffsfc.feature_support_compared_target_id' which should not be there.
It's obviously because the second argument of ->condition seems only accept variable. Anyone know how I can make a condition with two db fields with db_select?
Thanks for any help you can bring me.
Use $query->where($snippet, $args = array());
$query->where('cfsfc.feature_support_compared_target_id = fpffsfc.feature_support_compared_target_id');

Drupal 7 altering query in view

I'm trying to alter a query in a view using mymodule_views_pre_execute and have used devel to find the sql query it is currently using, which is below:
SELECT node.nid AS nid FROM node node LEFT JOIN field_data_field_date
field_data_field_date ON node.nid = field_data_field_date.entity_id AND
(field_data_field_date.entity_type = :views_join_condition_0 AND
field_data_field_date.deleted = :views_join_condition_1)
WHERE ((
(DATE_FORMAT(field_data_field_date.field_date_value, '%Y-%m-%d\T%H:%i') > :node_date_filter) )AND
(( (node.status = :db_condition_placeholder_2) )))
LIMIT 10 OFFSET 0
I am then re-doing this using the following:
$query = db_select("node", "n");
$query->addField("n", "nid");
$query->leftJoin("{field_data_field_date}", "{field_data_field_date}",
"n.nid = field_data_field_date.entity_id AND field_data_field_date.entity_type = 'node'
AND field_data_field_date.deleted = '0'");
$query->where("(DATE_FORMAT(field_data_field_date.field_date_value, '%Y-%m-%d\T%H:%i') > NOW())");
$query->where("n.status = '1'");
I've had to replace :views_join_condition_0 with 'node', :views_join_condition_1 with '0' and :node_date_filter to NOW() although i'm not sure if this is the correct way? If I leave :views_join_condition_0, :views_join_condition_1 and :node_date_filter in though it doesn't work?!
Use hook_view_query_alter(&$view, &$query) instead.

Resources