当我单独运行时,带有内部联接子查询的select查询会起作用,但会在存储过程的上下文中导致错误Unknown column 'cities.state' in 'on clause'
。什么可能导致通常在存储过程中打破的查询?为什么会为cities.state
而不是cities.name
返回此未知列错误? MySQL 5.7
CREATE DEFINER=`root`@`localhost` PROCEDURE `geogen`(IN State CHAR(2), CityMin INT(5), CityMax INT(6))
BEGIN
#Create a temporary table to hold the final GeoArea product
DROP TABLE IF EXISTS `geodb`.`geoareas`;
CREATE TEMPORARY TABLE `geodb`.`geoareas` LIKE `geodb`.`geoareatemplate`;
INSERT INTO `geodb`.`geoareas` (`geoarea`, `zip`, `state`)
# Zip code sets of cities/towns with a population between CityMin and CityMax are their own GeoAreas.
SELECT CONCAT(`uszipcode`.`name`, ' ', `uszipcode`.`state`) as 'geoarea', `uszipcode`.`zip`, `uszipcode`.`state`
FROM `geodb`.`uszipcode`
INNER JOIN
(SELECT `name`, `state`, SUM(`population`) AS 'Population'
FROM `geodb`.`uszipcode`
WHERE `uszipcode`.`state` = State
GROUP BY `name`
HAVING (SUM(`population`) >= CityMin AND SUM(`population`) <= CityMax)) as `cities`
ON `uszipcode`.`name` = `cities`.`name`
AND `uszipcode`.`state` = `cities`.`state`
ORDER BY `uszipcode`.`name`, `uszipcode`.`zip`;
SELECT * FROM geodb.geoareas;
END
当我使用
运行此查询时CALL geogen('TX', 35000, 70000);
我收到错误
0 76 13:10:22 CALL geogen('TX', 35000, 70000) Error Code: 1054. Unknown column 'cities.state' in 'on clause' 0.031 sec
但是,当我自己运行查询时,会返回结果。
SELECT CONCAT(`uszipcode`.`name`, ' ', `uszipcode`.`state`) as 'geoarea', `uszipcode`.`zip`, `uszipcode`.`state`
FROM `geodb`.`uszipcode`
INNER JOIN
(SELECT `name`, `state`, SUM(`population`) AS 'Population'
FROM `geodb`.`uszipcode`
WHERE `uszipcode`.`state` = 'TX'
GROUP BY `name`
HAVING (SUM(`population`) >= 30000 AND SUM(`population`) <= 70000)) as `cities`
ON `uszipcode`.`name` = `cities`.`name`
AND `uszipcode`.`state` = `cities`.`state`
ORDER BY `uszipcode`.`name`, `uszipcode`.`zip`;
结果
LIMIT 0, 1000 121 row(s) returned 0.453 sec / 0.000 sec
答案 0 :(得分:2)
MySQL很困惑,因为名为State
的参数/变量与列名cities.state
类似。我相信这是一个MySQL错误,因为我使用反引号并通过在表名前面添加显式引用该列,但如果我错了请纠正我,这是预期的行为。当我将State
参数更新为VarState
时,存储过程的结果与独立查询的结果相匹配,如下所示。
CREATE DEFINER=`root`@`localhost` PROCEDURE `geogen`(IN VarState CHAR(2), CityMin INT(5), CityMax INT(6))
BEGIN
#Create a temporary table to hold the final GeoArea product
DROP TABLE IF EXISTS `geodb`.`geoareas`;
CREATE TEMPORARY TABLE `geodb`.`geoareas` LIKE `geodb`.`geoareatemplate`;
# Zip code sets of cities/towns with a population between CityMin and CityMax are their own GeoAreas.
INSERT INTO `geodb`.`geoareas` (`geoarea`, `zip`, `state`)
SELECT CONCAT(`uszipcode`.`name`, ' ', `uszipcode`.`state`) as 'geoarea', `uszipcode`.`zip`, `uszipcode`.`state`
FROM `geodb`.`uszipcode`
INNER JOIN
(SELECT `name`, `state`, SUM(`population`) AS 'Population'
FROM `geodb`.`uszipcode`
WHERE `uszipcode`.`state` = VarState
GROUP BY `name`
HAVING (SUM(`population`) >= CityMin AND SUM(`population`) <= CityMax)) AS `cities`
ON `uszipcode`.`name` = `cities`.`name`
AND `uszipcode`.`state` = `cities`.`state`
ORDER BY `uszipcode`.`name`, `uszipcode`.`zip`;
SELECT * FROM geodb.geoareas
ORDER BY `geoarea`, `zip`;
END
答案 1 :(得分:1)
尝试将applySignals
包裹在SELECT
中,如下所示:
()
答案 2 :(得分:1)
试试这个:
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `geogen`(IN State CHAR(2), CityMin INT(5), CityMax INT(6))
BEGIN
#temp cities
DROP TABLE IF EXISTS `geodb`.`cities_temp`;
CREATE TEMPORARY TABLE `geodb`.`cities_temp`
SELECT `name`, `state`, SUM(`population`) AS 'Population'
FROM `geodb`.`uszipcode`
WHERE `uszipcode`.`state` = State
GROUP BY `name`
HAVING (SUM(`population`) >= CityMin AND SUM(`population`) <= CityMax) ;
#Create a temporary table to hold the final GeoArea product
DROP TABLE IF EXISTS `geodb`.`geoareas`;
CREATE TEMPORARY TABLE `geodb`.`geoareas` LIKE `geodb`.`geoareatemplate`;
INSERT INTO `geodb`.`geoareas` (`geoarea`, `zip`, `state`)
# Zip code sets of cities/towns with a population between CityMin and CityMax are their own GeoAreas.
SELECT CONCAT(`uszipcode`.`name`, ' ', `uszipcode`.`state`) as 'geoarea', `uszipcode`.`zip`, `uszipcode`.`state`
FROM `geodb`.`uszipcode`
INNER JOIN
`geodb`.`cities_temp` as `cities`
ON `uszipcode`.`name` = `cities`.`name`
AND `uszipcode`.`state` = `cities`.`state`
ORDER BY `uszipcode`.`name`, `uszipcode`.`zip`;
SELECT * FROM geodb.geoareas;
END$$
DELIMITER ;