Laravel produkuje pusty wynik, a query SQL daje poprawny wynik

0

Znowu mam problem z Laravelem i jak go tu mam lubić :P Ale do rzeczy.

Mam tabelę z obiektami, które mają swoje koordynaty lat/long. Chciałbym wybrać kilka z nich, ograniczonych do obszaru określonego przez skrajne punkty czworokąta. Wyprodukowałem więc zapytanie, które wygląda tak:

$objects = ModelObject::where('latitude', '>=', $minLat)->where('longitude', '>=', $minLon)->where('latitude', '<=', $maxLat)->where('longitude', '<=', $maxLon)->get();

i wraca pusta tabelka...

Gdy zrzucę te zapytanie z query loga to mam:

select * from `tablewithobjects` where `latitude` >= ? and `longitude` >= ? and `latitude` <= ? and `longitude` <= ?

oraz bindingi:

Array
(
    [0] => 51.501199
    [1] => -0.1579233
    [2] => 51.525043
    [3] => -0.1250157
)

Jeżeli wpiszę te zapytanie bezpośrednio do bazy podmieniając tokeny to wracają odpowiednie dane.

Przykładowe koordynaty jednego z obiektów, który powinien być w wynikach tego zapytania to: 51.503186 -0.150547.

Zauważyłem też, że jeżeli zamienię parametry zapytania 1 z 3 to wtedy Laravel zwraca poprawne dane, natomiast zapytanie odpalone bezpośrednio w bazie daje pusty wynik.

Nie rozumiem co tu jest grane :U

Przecież -0.150547 jest większe od -0.1579233 oraz mniejsze od -0.1250157, siedzę nad tym już tyle czasu, że aż musiałem się o to spytać Wolfram Alpha https://www.wolframalpha.com/input/?i=-0.150547+%3E%3D+-0.1579233+%26+-0.150547+%3C%3D+-0.1250157 który się ze mną zgadza. Dlaczego jednak w Laravelu jest z tym problem?

0

A jesteś pewien, że zmienne użyte w laravelu do zapytania mają poprawne dane ?

0
pol90 napisał(a):

A jesteś pewien, że zmienne użyte w laravelu do zapytania mają poprawne dane ?

Tak, to co podałem wyżej to zrzut z query loga Laravela, jeżeli po kolei podstawię te dane za tokeny w zapytaniu to uruchomione w dowolnym kliencie SQL dają poprawne wyniki, jednak w Laravelu wraca pusty zbiór danych. Nawet gdybym tam coś pomieszał to przecież tablica bindingów pokaże co tak na prawdę trafia do zapytania. W zasadzie to moge ograniczyć te query tylko do jednego warunku

DB::enableQueryLog();
$objects = ModelObject::where('longitude', '<=', $maxLon)->get();
print_r($objects);
print_r(DB::getQueryLog());

To wynik tego jest następujący

Illuminate\Database\Eloquent\Collection Object
(
    [items:protected] => Array
        (
        )

)
Array
(
    [0] => Array
        (
            [query] => select * from `tabelka` where `longitude` <= ?
            [bindings] => Array
                (
                    [0] => -0.1250157
                )

            [time] => 0
        )

)

Jeżeli wrzucę natomiast te zapytanie do klienta SQL i odpalę je to

select * from `tabelka` where `longitude` <= -0.1250157;
/* Affected rows: 0  Znalezionych wierszy: 3  Ostrzeżenia: 0  Czas przetwarzania 1 query: 0,000 sec. */

id;latitude;longitude
11;51.507350;-0.127758
12;51.503186;-0.150547
13;51.523056;-0.155181

// Dopisek
To jakiś problem z samym PDO jest, wykonałem te zapytanie za jego pomocą

array (size=1)
  0 => float -0.1250157

object(PDOStatement)[5]
  public 'queryString' => string 'select id, latitude, longitude from `restaurant` where `longitude` <= ?' (length=71)

i wynik to:

array (size=0)
  empty

Jeżeli umieszczę jednak zmienną bezpośrednio w zapytaniu to nagle staje się magia

object(PDOStatement)[5]
public 'queryString' => string 'select id, latitude, longitude from `restaurant` where `longitude` <= -0.1250157' (length=80)

array (size=3)
  0 => 
    array (size=3)
      'id' => string '11' (length=2)
      'latitude' => string '51.507350' (length=9)
      'longitude' => string '-0.127758' (length=9)
  1 => 
    array (size=3)
      'id' => string '12' (length=2)
      'latitude' => string '51.503186' (length=9)
      'longitude' => string '-0.150547' (length=9)
  2 => 
    array (size=3)
      'id' => string '13' (length=2)
      'latitude' => string '51.523056' (length=9)
      'longitude' => string '-0.155181' (length=9)

WTF?

// Dopisek #2

Hahaha dobra, zagadka rozwiązana, aż wstyd :P. Ale bym się nigdy nie domyślił, normalnie materiał na odcinek Usterki ;)

O co chodziło? Ktoś zrobił psikusa i ustawił w bazie kolumny lat/long jako varchar zamiast decimal, przez co były przez PDO bindowane jako string mimo podawania floatów i z jakiegoś powodu gubił się przy porównaniu minus.

1 użytkowników online, w tym zalogowanych: 0, gości: 1