J'essaie de créer une procédure stockée. Voici ce que j'ai jusqu'à présent (ne fonctionne pas):
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 est une fonction que j'ai créée qui fonctionne très bien. Comme vous pouvez le voir, j'essaie de prendre l'id d'une ville dans le tableau des villes, puis de définir cityLat et cityLng sur d'autres valeurs de cet enregistrement. Je fais évidemment cela mal ici en utilisant SELECTs.
Est-ce seulement possible. Il semble que ce devrait être le cas. Toute aide que ce soit sera grandement appréciée.
Correction de quelques éléments et ajout d'une sélection alternative - supprimer le cas échéant.
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 ;
Il vous suffit de mettre vos instructions SELECT
entre parenthèses pour indiquer qu'il s'agit de sous-requêtes:
SET cityLat = (SELECT cities.lat FROM cities WHERE cities.id = cityID);
Alternativement, vous pouvez utiliser la syntaxe SELECT ... INTO
de MySQL. Un avantage de cette approche est que cityLat
et cityLng
peuvent être attribués à partir d'un seul accès à la table:
SELECT lat, lng INTO cityLat, cityLng FROM cities WHERE id = cityID;
Cependant, la procédure entière peut être remplacée par une seule instruction SELECT
auto-jointe:
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;