PDO returning 0 rows on WHERE with enum
-
16-02-2021 - |
Pregunta
I am trying to build a query for a report. The report will have a few fields that can be filtered, one of which is a jobStatus
field, it is an enum.
Here is my query
SELECT * FROM jobs j
LEFT JOIN property p ON j.propertyID = p.propertyID
LEFT JOIN property_buildings b ON b.buildingID = j.buildingID
LEFT JOIN departments d ON j.dptID = d.dptID
LEFT JOIN jobs_timeframe jt ON j.jobTimeframeID = jt.jobTimeframeID
LEFT JOIN jobs_type t ON j.jobTypeID = t.jobTypeID
LEFT JOIN floors f ON f.floorID = j.floor
LEFT JOIN (
SELECT group_concat(a.assetNo) AS assets, ja.jobID
FROM jobs_assets ja
INNER JOIN assets a ON a.assetID = ja.assetID
GROUP BY jobID
ORDER BY assetNo ASC
) ja ON ja.jobID = j.jobID
LEFT JOIN (
SELECT group_concat(o.obsNo) AS observations, oj.jobID
FROM observationJobs oj
INNER JOIN observation o ON o.obsID = oj.obsID
GROUP BY jobID
ORDER BY obsNo ASC
) jo ON jo.jobID = j.jobID
WHERE j.ClientID = :clientID AND j.jobStatus = :status
LIMIT :limit OFFSET :offset
Here are my bound parameters: :clientID => 14, :status => 'Draft', :limit => 25, :offset => 0
If i exclude the j.jobStatus
it works fine and shows 19 results with a mix of jobStatus' including Draft
, Finished
and Approved
If i include try and filter by j.jobStatus
at all using PDO i get a successful query but with zero rows (should be 14 rows for Draft
, 1 for Approved
, 3 for Finished
and 1 null)
if i unsafely just put the variable for :status in the query
(like this WHERE j.ClientID = :clientID AND j.jobStatus = '.$status.' LIMIT :limit OFFSET :offset
)
it works fine and shows the 14 expected results. I can not for the life of me figure out why.
The only thing I can think of is it is something to do with it being an enum, but i was under the impression that they are treated as strings for everything except the actual storage.
EDIT: binding code:
$stmt->bindParam(':limit', $lim, PDO::PARAM_INT);
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
$stmt->bindParam(':status', $params[':status'], PDO::PARAM_STR);
$stmt->bindParam(':clientID', $params[':clientID'], PDO::PARAM_INT);
Solución
Turns out it was the foreach loop i was using to bind the parameters as seen in this issue on stackoverflow
for anyone who comes across a similar issue in the future the following will fail:
foreach($params AS $k => $v){
$stmt->bindParam($k, $v);
}
as bindParam does not actually bind it when you call it, it just binds a link to $v
so it will always be the last item it the loop. to overcome this, you need to pass the argument by reference as follows:
foreach($params AS $k => &$v){
$stmt->bindParam($k, $v);
}
notice the &
before $v
in the foreach, cause it to work as expected.