Doctrine inner query set parameters - symfony

I'm trying to execute an inner query and set parameters without success, i always get:
Invalid parameter number: number of bound variables does not match number of tokens
This is my query :
SELECT i2
FROM MyBundle:Identity i2
INNER JOIN MyBundle:Property\\Mapped\\Email propertyEmail WITH propertyEmail.identity = i2
INNER JOIN MyBundle:Channel channel WITH propertyEmail.channel = channel
WHERE (
SELECT COUNT(mappedEmail)
FROM MyBundle:Property\\Mapped\\Email mappedEmail
WHERE mappedEmail.identity = i2
AND mappedEmail.channel = :channel
AND mappedEmail.createdAt <= :dateFrom
) > 0
AND IDENTITY(propertyEmail.channel) <> :channel
AND propertyEmail.createdAt <= :dateFrom
GROUP BY i2
And this is how i put as subquery:
$innerQuery = $queryBuilder->getEntityManager()->createQuery($query)
->setParameters([
'channel' => $channelId,
'dateFrom' => $dateFrom
])
;
$queryBuilder->andWhere($queryBuilder->expr()->notIn($alias, $innerQuery->getDQL()));
That return the error :
Invalid parameter number: number of bound variables does not match number of tokens
If I execute the query as single query all works right.
Thanks for suggestion.

Try to apply the parameters to the main query as follow:
$innerQuery = $queryBuilder->getEntityManager()->createQuery($query);
$queryBuilder
->andWhere($queryBuilder->expr()->notIn($alias, $innerQuery->getDQL()))
->setParameters([
'channel' => $channelId,
'dateFrom' => $dateFrom
]);

Related

How to add a count number to an array of data : Doctrine

In fact, after returning a result of data from the database using Doctrine,
I'm trying to add the row count number, without calling another query request.
This is my function:
public function search(QueryBuilder $qb, string $search)
{
$qb = $qb->addSelect('COUNT(n) as count');
$search = $this->escape($search);
$qb->andWhere(
$qb->expr()->like('n.title', $qb->expr()->literal('%'.$search.'%'))
);
$qb->setMaxResults(2);
}
This is my DQL:
SELECT n, COUNT(n) as count FROM CoreBundle\Entity\News n LEFT JOIN n.category c WHERE n.title LIKE '%re%'
And I need to return as a result a all my data with a count key that refer to the number of rows.
The problem that I'm getting only the first row with id = 1, and it seems that the count number is correct.
So the result should by something like that:
['count' => 2 , [Newsn1,Newsn2]
Don't tell me to use array_count because I need to get the count of rows in the database, and I have a setMaxResults function, so I will not get a real number of rows.
I don't know the configuration of your table, I just can imagine. So, here's my try:
For getting counts for all titles in your table:
# SQL
SELECT COUNT(id) AS count, GROUP_CONCAT(title SEPARATOR ', ') AS titles FROM newses GROUP BY title
# DQL. assuming you are using a Repository method:
$qb = $this->createQueryBuilder('n');
$qb
->select("COUNT(n.id) AS count, GROUP_CONCAT(n.title SEPARATOR ', ') AS titles")
->leftJoin('n.category', 'c')
->groupBy('n.title')
;
return $qb->getQuery()->getArrayResult();
For getting counts for a particular title:
# SQL
SELECT COUNT(id) AS count, GROUP_CONCAT(title SEPARATOR ', ') AS titles FROM newses WHERE n.title LIKE '%news%' GROUP BY title
# NewsRepository.php
public function getTitlesCount($title)
{
$qb = $this->createQueryBuilder('n');
$qb
->select("COUNT(n.id) AS count, GROUP_CONCAT(n.title SEPARATOR ', ') AS titles")
->leftJoin('n.category', 'c')
->where('n.title LIKE :title')
->setParameter('title', "%{$title}%")
->groupBy('n.title')
;
return $qb->getQuery()->getArrayResult();
}

Query to Fetch Data from Database

I am fetching data from SQLite database using following query:
SELECT p.sent,
e.*,
e.no _id
FROM ecare e
LEFT OUTER JOIN pweb p ON e.h_id = p.h_id
WHERE (ant = 'N' or ant = 'D')
GROUP BY e.h_id
ORDER BY p.sent
By using the above SQLite query, I am getting all the records belonging to sent (where sent = 1 and sent = 0).
Now, I would like to get only those records from database, where sent status is sent = 0. (In short, I don't want to fetch all the records belonging to sent, or records where sent = 1).
Have you tried with below query ?
SELECT p.sent,e.*, e.no _id from ecare e LEFT JOIN pweb p ON
e.h_id=p.h_id WHERE (ant = 'N' or ant = 'D') AND p.sent = '0' GROUP
BY e.h_id
Check below query for your question:
return db.rawQuery("SELECT p.sent,e.*, e.no _id from ecare e LEFT OUTER JOIN pweb p ON e.h_id=p.h_id WHERE (ant = 'N' or ant = 'D') AND p.sent = '1' GROUP BY e.h_id ORDER BY p.sent ", null);
You are already filtering on the ant column.
Adding a filter for sent works the same way:
SELECT ...
...
WHERE (ant = 'N' OR ant = 'D')
AND sent = 0
...

PL/SQL: Conditional Where

I have the following scenario:
CREATE OR REPLACE PROCEDURE GETINBOX
(
inHasAttachments IN int
)
AS
BEGIN
SELECT M.MailId,
M.SenderId,
E.Emp_Name As "Sender",
MI.RecipientId,
M.Subject
FROM MAIL M INNER JOIN MAILINBOX MI ON M.MailId = MI.MailId
WHERE MI.RecipientId = '547' AND
M.NotificationSelected = 'Y'
IF inHasAttachments = '1' THEN
AND M.Attachments = 'Y'
END IF;
END GETINBOX;
Is it possible to add conditions to the where clause based on the value of a parameter?
WHERE MI.RecipientId = '547' AND
M.NotificationSelected = 'Y'
IF inHasAttachments = '1' THEN
AND M.Attachments = 'Y'
END IF;
Obviously this is not allowed but is it possible to do this in some way in PL/SQL?
I know one way to do it is to duplicate the query and execute a different query based on the value of the parameter but I don't want to duplicate my code.
As I understand your requirements: if the value of parameter inHasAttachments is 1 then you want to filter further by M.Attachments = 'Y', and if its value isn't 1 then you don't care about M.Attachments. This is in addition to the condition MI.RecipientId = '547' AND M.NotificationSelected = 'Y'.
You can do it like this:
SELECT M.MailId,
M.SenderId,
E.Emp_Name As "Sender",
MI.RecipientId,
M.Subject
FROM MAIL M INNER JOIN MAILINBOX MI ON M.MailId = MI.MailId
WHERE MI.RecipientId = '547' AND M.NotificationSelected = 'Y'
AND (inHasAttachments <> '1' OR M.Attachments = 'Y')

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.

SQL Select fields with a value of 'Y' and order by date descending, then select all others and order by another field ascending

I am generating an SQL query:
SELECT * FROM ToDoList
WHERE ws_status <> 'Completed'
AND (user_id= 'TESTUSR' OR ww_cover='TESTUSR'
OR (ws_status = 'Orphan' AND wwt_workgroupid IN (108)))
**ORDER BY psc_alt_code ASC**
And I need to list all results with wi_urgent set to 'Y' and order them by date Desc *first and then list all other results ordered by psc_alt_code descending* so I thought something like this would suffice:
ORDER BY (wi_urgent = 'Y') DESC, psc_alt_code ASC
I am getting SqlClient.SqlException: Incorrect syntax near '=' error when trying to run that query. Please note that I am querying an SQL View if that makes a difference?
You can use a case expression in the order by
SELECT * FROM ToDoList
WHERE ws_status <> 'Completed'
AND (user_id= 'TESTUSR' OR ww_cover='TESTUSR'
OR (ws_status = 'Orphan' AND wwt_workgroupid IN (108)))
ORDER BY CASE WHEN wi_urgent = 'Y' THEN 0 ELSE 1 END ASC
,psc_alt_code
I don't think you can do wi_urgent = 'Y' in an ORDER BY.
Since you're looking for all results with wi_urgent, try adding it to the WHERE clause:
SELECT * FROM ToDoList
WHERE ws_status <> 'Completed'
AND (user_id= 'TESTUSR' OR ww_cover='TESTUSR'
OR (ws_status = 'Orphan' AND wwt_workgroupid IN (108)))
AND wi_urgent = 'Y'
ORDER BY wi_urgent DESC,
psc_alt_code ASC

Resources