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);
有帮助吗?

解决方案

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.

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top