在PhpMyAdmin中运行时,哪里给我不同的结果

时间:2018-10-07 14:48:44

标签: mysql laravel

当我在phpMyAdmin中运行以下查询时

    SELECT 
        locations.name,
        locations.id,
        locations.lon,
        locations.lat,
        locations_categories.category_id as catId,
        locations_categories.location_id as locId,
        haversine(40,90,locations.lon,locations.lat) as distance
    FROM locations_categories, locations  
    WHERE locations.id = locations_categories.location_id
    AND locations_categories.category_id IN ("9","1","7")  
    ORDER BY `distance` ASC

它给了我以下正确的结果。

enter image description here

但是当我在Laravel应用程序中运行以下命令时,它仅返回catId为9的位置。

        // dump($request->categories);
        $categories = implode('","',$request->categories);

        //dd($categories);


        $statement = <<<'ENDSTATEMENT'
        SELECT 
            locations.name,
            locations.id,
            locations.lon,
            locations.lat,
            locations_categories.category_id as catId,
            locations_categories.location_id as locId,
            haversine(?,?,locations.lon,locations.lat) as distance
        FROM locations_categories, locations  
        WHERE locations.id = locations_categories.location_id
        AND locations_categories.category_id IN (?)  
        ORDER BY `distance` ASC
ENDSTATEMENT;

    $locations = DB::select($statement, array($request->lon, $request->lat, $categories));

的结果
dd($categories);

是以下屏幕截图

enter image description here

我的问题是,为什么这样做有效并返回PhpMyAdmin中所需的所有值,但在应用程序中运行时却不能返回?

3 个答案:

答案 0 :(得分:2)

在此处使用Laravel代码,而不是单个原始查询。这使您可以利用 <script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> 函数,该函数可以将PHP值数组正确绑定到whereIn表达式。

WHERE

答案 1 :(得分:2)

您的问题的答案与如何实现绑定变量以及强制类型结合在一起。

绑定的:///////被单个值替换。这不是对SQL语句的简单搜索和替换。因此,在?中,locations_categories.category_id IN (?)的值实际上是整个值?。但是,为什么仍返回9","1","7处的结果?

由于强制类型。我假设locations_categories.category_id = 9是数字,而不是架构中的字符类型列。因此,在执行SQL时,右侧的字符串值locations_categories.category_id被强制转换为数字表示形式,恰好是9","1","7。您可以在此处更明确地看到它:

9

答案 2 :(得分:0)

原始查询必须像这样,并传递一个参数数组以绑定到select:

SELECT 
    locations.name,
    locations.id,
    locations.lon,
    locations.lat,
    locations_categories.category_id as catId,
    locations_categories.location_id as locId,
    haversine(:req_lon, :req_lat, locations.lon, locations.lat) as distance
FROM locations_categories, locations  
WHERE 
    locations.id = locations_categories.location_id AND 
    locations_categories.category_id IN (:cat0, :cat1, :cat2)  
ORDER BY `distance` ASC

使用带有参数的代码进行绑定:

$categories = ["9","1","7"]; // example

$bind = [];
foreach($categories as $k => $cat) {
    $bind['cat'.$k] = $cat;
}
$listCat = implode(', ', array_keys($bind));

// add others filters
$bind['req_lon'] = $request->lon;
$bind['req_lat'] = $request->lat;

$sql = 
"   SELECT 
        locations.name,
        locations.id,
        locations.lon,
        locations.lat,
        locations_categories.category_id as catId,
        locations_categories.location_id as locId,
        haversine(:req_lon, :req_lat, locations.lon, locations.lat) as distance
    FROM locations_categories, locations  
    WHERE 
        locations.id = locations_categories.location_id AND 
        locations_categories.category_id IN ({$listCat})  
    ORDER BY `distance` ASC";

$locations = DB::select($sql, $bind);