Join query exception in Symfony 1.4.11/Propel 1.4.2 - symfony-1.4

I need to run following query:
SELECT
m.TITLE,
m.MOMENTOIMAGE,
s.CREATED_AT,
s.UNREAD,
mem.FIRSTNAME,
mem.LASTNAME,
mem.MEMBER_PHOTO,
mem.ID
FROM `momento_send` s,
`send_distribution` sd,
`momento_distribution` d,
`momento` m,
`member` mem
WHERE
s.momento_idmember=6 AND
sd.id_send=s.id AND
sd.id_distribution=d.id AND
d.momento_id=m.id;
For that, I wrote following code in Symfony 1.4 (using Propel 1.4.2) (Thanks to #j0k)
$c = new Criteria();
$c->clearSelectColumns();
$c->addSelectColumn(MomentoPeer::TITLE);
$c->addSelectColumn(MomentoPeer::MOMENTOIMAGE);
$c->addSelectColumn(MomentoSendPeer::CREATED_AT);
$c->addSelectColumn(MomentoSendPeer::UNREAD);
$c->addSelectColumn(MemberPeer::FIRSTNAME);
$c->addSelectColumn(MemberPeer::LASTNAME);
$c->addSelectColumn(MemberPeer::MEMBER_PHOTO);
$c->addSelectColumn(MemberPeer::ID);
$c->addJoin(SendDistributionPeer::ID_SEND, MomentoSendPeer::ID, Criteria::INNER_JOIN);
$c->addJoin(SendDistributionPeer::ID_DISTRIBUTION, MomentoDistributionPeer::ID, Criteria::INNER_JOIN);
$c->addJoin(MomentoDistributionPeer::MOMENTO_ID, MomentoPeer::ID, Criteria::INNER_JOIN);
$c->addJoin(MomentoDistributionPeer::MOMENTO_IDMEMBER, MemberPeer::ID, Criteria::INNER_JOIN);
$c->add(MomentoSendPeer::MOMENTO_IDMEMBER, $memberid);
//echo $c->toString();exit;
$records = SendDistributionPeer::doSelect($c);
Running this code generated following error
[wrapped: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER JOIN momento_send ON (send_distribution.ID_SEND=momento_send.ID) INNER JOI' at line 1]
Can someone suggest, what is the issue.
Just to give little more info, SQL printed with echo $c->toString();exit; was
SELECT momento.TITLE,
momento.MOMENTOIMAGE,
momento_send.CREATED_AT,
momento_send.UNREAD,
member.FIRSTNAME,
member.LASTNAME,
member.MEMBER_PHOTO,
member.ID
FROM
INNER JOIN momento_send ON (send_distribution.ID_SEND=momento_send.ID)
INNER JOIN momento_distribution ON (send_distribution.ID_DISTRIBUTION=momento_distribution.ID)
INNER JOIN momento ON (momento_distribution.MOMENTO_ID=momento.ID)
INNER JOIN member ON (momento_distribution.MOMENTO_IDMEMBER=member.ID)
WHERE momento_send.MOMENTO_IDMEMBER=6

Try with $c->setPrimaryTableName(MomentoPeer::TABLE_NAME);

Related

Symfony3.4 / Doctrine : subquery in FROM Clause : Error: Class 'SELECT' is not defined

I'm working on a Symfony 3.4 project and I'm trying to translate an sql query to DQL query but I get an Issue.
Mysql Query:
select sum(montant_paye)
from
(select montant_paye
from vente
where client_id = 1
and montant_paye > 0
order by date ASC
limit 2)
as T;
DQL Query (Error):
return $this->getEntityManager()
->createQuery('
SELECT SUM(montantPaye) as Total
FROM
SELECT v.montantPaye
FROM AppBundle:Vente v
where v.montantPaye > 0
AND v.client = '.$clientId.'
ORDER BY v.date ASC
limit 2
')
->getResult();
Error :
[Semantical Error] line 0, col 71 near 'SELECT v.montantPaye
': Error: Class 'SELECT' is not defined.
Is any one have a solution for a correct DQL query ?
Quoting from Christophe stoef Coevoet (Symfony Core Developer):
DQL is about querying objects. Supporting subselects in the FROM clause means that the DQL parser is not able to build the result set mapping anymore (as the fields returned by the subquery may not match the object anymore).
This is why it cannot be supported (supporting it only for the case you run the query without the hydration is a no-go IMO as it would mean that the query parsing needs to be dependant of the execution mode).
In your case, the best solution is probably to run a SQL query instead
(as you are getting a scalar, you don't need the ORM hydration anyway)
Details here.
add this function to your VenteRepository:
public function sumMontantPaye($clientId)
{
return $this->createQueryBuilder("v")
->select("sum(v.montantPaye) as sum")
->where("v.client = :id")
->andWhere("v.montantPaye > 0")
->setParameter("id", $clientId)
->setMaxResults(2)
->getQuery()->getSingleResult();
}
you can access the sum using $result["sum"] assuming $result is the variable assigned to this function in the controller

What's wrong with my query and what does the error mean?

I cannot figure what's wrong with this query and what the error means:
Query
select Total2014, Total2015
From 2014_Jan_Pivot
inner join 2015_Jan_Pivot on 2014_Jan_Pivot.PremiseCity2014=
2015_Jan_Pivot.PremiseCity2015
Error says:
unrecognized token: "2014_Jan_Pivot": select Total2014, Total2015, Total2016, Total2017
From 2014_Jan_Pivot
Your issue is because names in SQLite cannot start with a digit/number unless they are enclosed.
So 2014_Jan_Pivot is an invalid (aka unrecognised) token.
However, you can enclose the name and it will then be recognised e.g. :-
[2014_Jan_Pivot]
`2014_Jan_Pivot`
"2014_Jan_Pivot" or
'2014_Jan_Pivot'
So your query could be :-
SELECT
Total2014,
Total2015
FROM [2014_Jan_Pivot]
INNER JOIN [2015_Jan_Pivot] ON
[2014_Jan_Pivot].PremiseCity2014 = [2015_Jan_Pivot].PremiseCity2015

SQLite Join OperationalError

When running this SQL code with join, I got an error:
ss= 'select project.id from project_list pl '
ss+= ' LEFT JOIN project p ON pl.project_id = p.id '
ss+= ' LEFT JOIN table t ON pl.table_id = t.id '
Error is :
OperationalError: (sqlite3.OperationalError) near "table":
syntax error [SQL: 'select project.id from project_list pl
LEFT JOIN project p ON pl.project_id = p.id LEFT JOIN table t
ON pl.table_id = t.id ']
This is not where the error comes from since the SQL statement looks correct.
This is using SQL Alchemy.
If you have a table named table, you need to quote it, or it causes a parsing error. This will work:
ss= 'select project.id from project_list pl '
ss+= ' LEFT JOIN project p ON pl.project_id = p.id '
ss+= ' LEFT JOIN "table" t ON pl.table_id = t.id '
This is because table is a reserved word in SQL (e.g. create table my_table, alter table mytable, etc.), and either the SQL parser is primitive, or the spec demands that it behave this way (PostgreSQL has the same problem).
I strongly encourage you to rename table to something else, if you can, or you're going to be in for a world of hurt. In other scenarios with SQLAlchemy or other DB libraries, when you're not hand-crafting the SQL, they may not be smart enough to automatically quote the table name. This will also cause you headaches if you migrate from SQLite to another database. It's likely to confuse people reading the code.

DBAL - symfony2 bind a value for LIKE operator

I am trying to execute a sql query that involves a LIKE operator with DBAL
Basically my query is the following:
public function getSubsiteByHostname($host){
$sql = "SELECT A.id, A.title, A.layout_id
FROM sites AS A
LEFT JOIN layouts B
ON A.layout_id = B.id
WHERE A.baseurl LIKE '%:host%'
";
$stmt = $this->db->prepare($sql);
$stmt->bindValue("host", $host);
$stmt->execute();
return $stmt->fetch();
}
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'hostname.dev'%
Obiviously I'm doing something wrong with the bindValue
The answer is easier than I thought, like Adam suggested
$stmt->bindValue("host", '%'.$host.'%');

INTERVAL 1 MONTH not working With symfony2 doctrine?

I am stuck here and i spend last 2 days resolving this issue but failed. I am writing a query inside my repository to get the entries for current month. here is my query:-
$this->getEntityManager()
->createQuery('SELECT count(a) FROM CollegeStudentBundle:StudentAttendance a where a.student_id='.$id.'
and a.date > DATE_SUB(CURRENT_TIMESTAMP(),INTERVAL 1 MONTH)')
When I try to run this it gives me an error
[Syntax Error] line 0, col 133: Error: Expected Doctrine\ORM\Query\Lexer::T_COMMA, got '1'
Even I tried this thing but didn't helped me.
You should use parameter binding:
$query = $em->createQuery('SELECT count(a) FROM CollegeStudentBundle:StudentAttendance a where a.student_id = :id and a.date > :date');
$query->setParameter('id', $id);
$query->setParameter('date', new \DateTime('-1 month'));
You have to remember that DQL is not SQL. The error comes from Doctrine's Lexer and not from MySQL. DQL doesn't support INTERVAL (see list of supported functions).
Read more on adding your own functions, specifically adding DATE_ADD with INTERVAL support here: http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/cookbook/dql-user-defined-functions.html#date-add

Resources