I’m trying to write the following SQL query with QueryBuilder way:
SELECT * FROM oc_mf_jobs j WHERE j.status="pending" AND NOT EXISTS (
SELECT 1 FROM oc_mf_jobs WHERE status="processing" AND (
j.file_source IN (file_source, file_target) OR
( j.file_target IS NOT NULL AND j.file_target IN (file_source, file_target) )
)
) ORDER BY j.priority DESC, j.id LIMIT 1;
This is what i have so far, there should be somehow described inner SQL part with AND NOT EXISTS (…) part:
If you know where to start looking – i would really appreciate it.
P.S.: just for details/context — the idea is to select single row, which has “pending” state, while there is no currently any row with “processing” state which has matching file_source or file_target (basically meaning that this file is currently in processing state by other job); the file_target can be null, but not file_source.
SELECT *
FROM oc_mf_jobs j
WHERE j.status = 'pending'
AND NOT EXISTS (
SELECT 1
FROM oc_mf_jobs
WHERE status = 'processing'
AND (
j.file_source IN (file_source, file_target) OR
(j.file_target IS NOT NULL AND j.file_target IN (file_source, file_target))
)
)
ORDER BY j.priority DESC, j.id
LIMIT 1;
Here’s how to translate this SQL query into QueryBuilder PHP syntax:
Thank you for the help, but this still doesn’t work.
Execution gives error:
Code: 0
Message: Named parameter “pending” does not have a bound value.
This is my code. Its inside a method, which is expected to return an entity, which can be absent (there might not be next job, a valid situation). The method is a part of a mapper class which extends QBMapper, I’m telling this details, because in your code you use $this->getConnection(), i don’t have it. I do have db property which is injected via contructor and any query I build, I do $this->qb->getQueryBuilder(). Maybe this is important, so i mentioning this.
So the method which contains code you gave is following (and it gives error i mention above).
I don’t see why “pending” doesn’t have bound value as it clearly does. Maybe you see.
Also, do you know a way to simply execute a query from SQL? I checked implementations of IQueryBuilder and its just QueryBuilder class. And findEntities which is called at the end expects only IQueryBuilder.
To execute a SQL query directly, you can use the methods provided by the Doctrine DBAL library, like
// 1. Create the SQL query
$sql = "
SELECT *
FROM oc_mf_jobs j
WHERE j.status = :pending
AND NOT EXISTS (
SELECT 1
FROM oc_mf_jobs sq
WHERE sq.status = :processing
AND (
j.file_source IN (sq.file_source, sq.file_target) OR
(j.file_target IS NOT NULL AND j.file_target IN (sq.file_source, sq.file_target))
)
)
ORDER BY j.priority DESC, j.id
LIMIT 1
";
// 2. Set the parameters
$params = [
'pending' => 'pending',
'processing' => 'processing'
];
// 3. Execute the query
$stmt = $this->db->getConnection()->executeQuery($sql, $params);
// 4. Fetch the results
$result = $stmt->fetchAll();
// Process or return the results
return count($result) == 1 ? $result[0] : null;