Запрос PDOStatement с подзапросами возвращает пустой результат
У меня есть следующий код PHP, который странное поведение. Система опирается на базу данных PostgreSQL, версия PHP - 5.3.15.
$sql = "SELECT ce.id FROM calendar_events AS ce
WHERE ce.rowid = :rowid
AND ((SELECT count(*) FROM calendar_events_attendees AS cea WHERE cea.event_id = ce.id AND cea.status <> 'D') > 0
OR (SELECT count(*) FROM calendar_events_globalfnbl AS ceg WHERE ceg.event_id = ce.id AND ceg.status <> 'D') > 0)";
$stmt = db_prepare($sql); // Creates a PDOStatement
$stmt->bindValue(":rowid", $rowid, PDO::PARAM_INT);
$rv = $stmt->execute();
if($rv) {
return $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
}
else {
return null;
}
Запрос выполняется без ошибок, но функция возвращает пустой массив. Определенно, в базе данных есть строки, которые я могу найти. Если я выполню запрос в pgAdmin (местозаполнитель заменяется на идентификатор, о котором идет речь, конечно), он вернет строки, которые я хочу получить.
Мне удалось выяснить, что подзапросы являются проблемой здесь. Если я закомментирую их и использую следующий запрос, строки будут возвращены. Но, конечно, это также возвращает строки, которые я пытаюсь отфильтровать с помощью подзапросов.
$sql = "SELECT ce.id FROM calendar_events AS ce
WHERE ce.rowid = :rowid";
PDO просто не поддерживает этот тип подзапросов или в моем коде есть ошибка, которую я не могу найти?
Заранее спасибо!
2 ответа
Это была не проблема с PDO, а с моим кодом. После двойной проверки кода, вызывающего вышеупомянутую функцию снова и снова, я нашел несколько операторов, которые устанавливают статус 'D' для рассматриваемых строк ДО того, как был выполнен вышеуказанный код.
Так что этот вопрос сейчас устарел, извините за тратить время, ребята!
Я не знаю о твоих рамках, но твоя COUNT(*) > 0
подзапросы кажутся эквивалентными EXISTS (...)
подзапросы (которые также могут быть быстрее, так как они не должны считать все удовлетворяющие кортежи)
SELECT ce.id
FROM calendar_events AS ce
WHERE ce.rowid = :rowid
AND ( EXISTS (SELECT *
FROM calendar_events_attendees AS exa
WHERE exa.event_id = ce.id AND exa.status <> 'D'
)
OR EXISTS (SELECT *
FROM calendar_events_globalfnbl AS exg
WHERE exg.event_id = ce.id AND exg.status <> 'D'
)
);