2012-05-18 3 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 | 

гаверсинуса функция Я создал, которая работает отлично. Как вы можете видеть, я пытаюсь взять идентификатор города из таблицы городов, а затем установить cityLat и cityLng для некоторых других значений этой записи. Я, очевидно, делаю это неправильно, используя SELECT.

Это даже возможно. Кажется, это должно быть. Любая помощь будет очень признательна.

ответ

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); 

В качестве альтернативы, вы можете использовать SELECT ... INTO синтаксис для MySQL. Одним из преимуществ такого подхода заключается в том, что оба cityLat и cityLng могут быть назначены из одной таблицы-доступ:

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;