2012-05-18 80 views
7

我試圖創建一個存儲過程。這是我到目前爲止(不工作):MySQL從SELECT語句存儲過程變量

DELIMITER | 
CREATE PROCEDURE getNearestCities(IN cityID INT) 
    BEGIN 
     DECLARE cityLat FLOAT; 
     DECLARE cityLng FLOAT; 
     SET cityLat = SELECT cities.lat FROM cities WHERE cities.id = cityID; 
     SET cityLng = SELECT cities.lng FROM cities WHERE cities.id = cityID; 
     SELECT *, HAVERSINE(cityLat,cityLng, cities.lat, cities.lng) AS dist FROM cities ORDER BY dist LIMIT 10; 
    END | 

HAVERSINE是我創建的功能,它工作正常。正如你所看到的,我試圖從城市表中取一個城市的id,然後將cityLat和cityLng設置爲該記錄的其他值。我顯然在這裏通過使用SELECTs做錯了。

這甚至是可能的。它似乎應該是。任何幫助將不勝感激。

回答

12

更正了幾件事情,並根據需要添加了替代選擇 - 刪除。

DELIMITER | 

CREATE PROCEDURE getNearestCities 
(
IN p_cityID INT -- should this be int unsigned ? 
) 
BEGIN 

DECLARE cityLat FLOAT; -- should these be decimals ? 
DECLARE cityLng FLOAT; 

    -- method 1 
    SELECT lat,lng into cityLat, cityLng FROM cities WHERE cities.cityID = p_cityID; 

    SELECT 
    b.*, 
    HAVERSINE(cityLat,cityLng, b.lat, b.lng) AS dist 
    FROM 
    cities b 
    ORDER BY 
    dist 
    LIMIT 10; 

    -- method 2 
    SELECT 
     b.*, 
     HAVERSINE(a.lat, a.lng, b.lat, b.lng) AS dist 
    FROM  
     cities AS a 
    JOIN cities AS b on a.cityID = p_cityID 
    ORDER BY 
     dist 
    LIMIT 10; 

END | 

delimiter ; 
13

您只需在括號中放入你的SELECT聲明,以表明它們是子查詢:

SET cityLat = (SELECT cities.lat FROM cities WHERE cities.id = cityID); 

或者,你可以使用MySQL的SELECT ... INTO語法。這種方法的一個優點是,無論cityLatcityLng可以從單個表的訪問被分配:

SELECT lat, lng INTO cityLat, cityLng FROM cities WHERE id = cityID; 

然而,整個過程可以用一個自加入SELECT語句代替:

SELECT b.*, HAVERSINE(a.lat, a.lng, b.lat, b.lng) AS dist 
FROM  cities AS a, cities AS b 
WHERE a.id = cityID 
ORDER BY dist 
LIMIT 10; 
相關問題