2012-05-18 32 views
7

Saklı yordam oluşturmaya çalışıyorum. Ben bugüne kadar (çalışmıyor) sahip budur:MySQL SELECT deyimlerinin saklı yordam değişkenleri

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 çalışıyor benim yarattığım bir işlevdir. Görebildiğiniz gibi, şehir masasından bir şehrin kimliğini almaya çalışıyorum ve daha sonra cityLat ve cityLng değerini bu kaydın diğer değerlerine ayarlıyorum. Burada açıkça SELECTs kullanarak yanlış yapıyorum.

Bu mümkün mü? Olması gerektiği gibi görünüyor. Her türlü yardım büyük ölçüde takdir edilecektir. Eğer MySQL'ın SELECT ... INTO sözdizimi kullanabilirsiniz Alternatif

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

:

cevap

12

Birkaç şeyi düzeltin ve alternatif bir seçim ekleyin - uygun şekilde silin.

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

Sadece onlar subqueries olduğunu belirtmek için parantez içinde SELECT ifadeleri içine gerekir.

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

Ancak, tüm işlem tek kendini katıldı SELECT deyimi ile değiştirilebilir:

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; 
Bu yaklaşımın bir avantajı hem cityLat ve cityLng tek masa erişimden atanabilir olmasıdır
İlgili konular