15

我正在尝试创建一个存储过程。这是我到目前为止所拥有的(不工作):

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 设置为该记录的其他一些值。我显然在这里使用 SELECT 做错了。

这甚至可能吗。似乎应该如此。任何帮助将不胜感激。

4

3 回答 3

21

更正了一些事情并添加了替代选择 - 酌情删除。

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 ;
于 2012-05-18T09:47:38.390 回答
18

您只需将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;
于 2012-05-18T09:12:59.073 回答
0

我正面临一种奇怪的行为。

SELECT INTO 和 SET 两者都适用于某些变量而不适用于其他变量。事件语法相同

SET @Invoice_UserId :=  (SELECT UserId FROM invoice WHERE InvoiceId = @Invoice_Id  LIMIT 1); -- Working
                SET @myamount := (SELECT amount FROM invoice WHERE InvoiceId = @Invoice_Id LIMIT 1); - Not working
SELECT  Amount INTO @myamount FROM invoice WHERE InvoiceId = 29  LIMIT 1; - Not working

如果我直接运行这些查询然后可以工作,但不能在存储过程中工作。

于 2020-09-12T09:19:48.567 回答