MySQL存储过程中的变量如何从SELECT语句中获取

18

我正在尝试创建一个存储过程。这是我到目前为止的代码(不起作用):

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是我创建的一个很好用的函数。如您所见,我正试图从cities表中获取城市的id,然后将cityLat和cityLng设置为该记录的其他值。但是我在这里使用SELECT肯定是错误的。

这是否可能呢?看起来应该是可以的。非常感谢任何帮助。

3个回答

26

我纠正了一些问题并添加了一个替代选择 - 根据需要进行删除。

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 ;

19

您只需将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;

1
我面临着奇怪的行为。
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

如果我直接运行这些查询,则可以正常工作,但在存储过程中无法正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接