Где предложение, когда переменная false, не учитывает это в SQL-запросе?
У меня есть кое-что, что я не совсем понимаю, у меня есть решение, но я не знаю, почему и это заставляет меня немного сходить с ума
контроллер
DB::connection()->enableQueryLog();
$transfer = Transfer::where('ticket_id', $last_ticket)->where('event_id', 36)->where('buyer', $user_email)->first();
$queries = DB::getQueryLog();
dd($queries);
Результат
array:1 [
0 => array:3 [
"query" => "select * from 'transfers' where 'ticket_id' = ? and 'event_id' = ? and 'buyer' = ? limit 1"
"bindings" => array:3 [
0 => false
1 => 36
2 => "[email protected]"
]
"time" => 0.36
]
]
Ситуация: $last_ticket
в БД уникален и никогда не является null
, пустым или false
.
В моем примере $last_ticket
является false
, но в БД нет никакого false
, почему я все еще получаю результаты?
Это потому, что всякий раз, когда условие ложно, оно не принимает этого в уравнение?
Таким образом, возникает вопрос: как я могу сделать, чтобы получить правильные значения результатов: если $ last_ticket является ложным, то никаких результатов, и если у него есть некоторые данные, тогда возвращаем результат строки, ограниченный $ last_ticket
Один вариант может состоять в том, чтобы поставить if($last_ticket == false){$last_ticket='randomInexistentString_ag4dh&2g32y4t'}
чтобы он не был нулевым или нулевым, но я не думаю, что это более красивый способ пойти
Ответы
Ответ 1
Нуль в MySQL всегда соответствует любой строке, которая не начинается с цифры - это потому, что она хочет, чтобы обе стороны сравнения были одного типа, поэтому она преобразует строку в число, а любая строка, которая не начинать с цифры автоматически оценивается 0
.
Теперь вы не кормите его 0
но вы кормите его false
, а в MySQL - не истинным логическим, а фактически 0
.
Не зная точно, как выглядит ваша база данных, я бы сказал, что это наиболее вероятное объяснение.
Есть способы обойти это, например, вы можете использовать цепочку ->when()
в Eloquent:
Transfer::where('event_id', 36)
->where('buyer', $user_email)
->when($last_ticket, function ($query) use ($last_ticket) {
$query->where('ticket_id', $last_ticket);
})
->first();
(Взятый из памяти, синтаксис может немного отделиться. Спасибо Рику Джеймсу за исправление комментариев).
Ответ 2
Редизайн интерфейса. Если что-то нужно оставить вне запроса, не включайте его в запрос.
То есть, динамически создайте WHERE
, чтобы при поставке "false" оно становится
WHERE 'event_id' = ? and 'buyer' = ?
Я не знаю о Laravel, но в PHP я бы создал массив вещей для AND
и затем WHERE
:
$ands = array();
if (...) $ands[] = "ticket_id = ...";
if (...) $ands[] = "event_id = ...";
if (...) $ands[] = "buyer = ...";
if (empty($ands))
$where = '';
else
$where = 'WHERE ' . implode(' AND ', $ands);
$sql = "SELECT ... $where ...";
Обратите внимание, что он легко обрабатывает любой или все или ни один из элементов, которые опущены.