MY SQL中的存储过程IF语句返回错误1241

时间:2018-02-03 17:44:03

标签: mysql mysql-error-1241

我在MYSQL工作台中编写此代码,以检查多个表中的数据,以便在不重复的情况下在多个表中输入客户和各种客户详细信息,并从每个表中收集变量的主键,然后再转到下一个。我对INSERT语句使用了相同的IF ELSE语法,该语句完美无缺,但是在开头添加SELECT语句失败,在视图中检查customerID,最后检查UPDATE语句而不是INSERTS。

它失败并出现错误1241操作数应包含1列

我试图找到答案,并发现了很多关于此错误的问题,但没有一个与此语法有关。

有人可以帮忙吗?代码如下

CREATE DEFINER=`U03qew`@`%` PROCEDURE `sp_modify_customer`(IN CUST_ID INT(11), IN CUST_COUNTRY VARCHAR(50), 
IN CUST_NAME VARCHAR(45), IN CUST_ADDRESS VARCHAR(50), IN CUST_ADDRESS2 VARCHAR(50), IN CUST_CITY VARCHAR(50), 
IN CUST_ZIP VARCHAR(10), IN CUST_PHONE VARCHAR(20), IN CUR_USER VARCHAR(50))
BEGIN
DECLARE ccountryId VARCHAR(50);
DECLARE ccityId VARCHAR(50);
DECLARE caddressId VARCHAR(50);
IF (SELECT * FROM customer WHERE customerId = CUST_ID) IS NOT NULL THEN
BEGIN
IF (SELECT countryId FROM country WHERE country = CUST_COUNTRY) IS NOT NULL THEN
BEGIN
SELECT countryId FROM country WHERE country = CUST_COUNTRY
INTO ccountryId;
END;
ELSE BEGIN
INSERT INTO country (country, createDate, createdBy, lastUpdate, lastUpdateBy)
VALUES (CUST_COUNTRY, current_date(), CUR_USER, current_timestamp(), CUR_USER);
SELECT countryId FROM country WHERE country = CUST_COUNTRY
INTO ccountryId;
END;
END IF;
IF (SELECT cityId FROM city WHERE city = CUST_CITY AND countryId = ccountryId) IS NOT NULL THEN
BEGIN
SELECT cityId FROM city WHERE city = CUST_CITY AND countryId = ccountryId
INTO ccityId;
END;
ELSE BEGIN
INSERT INTO city (city, countryId, createDate, createdBy, lastUpdate, lastUpdateBy)
VALUES (CUST_CITY, ccountryId, current_date(), CUR_USER, current_timestamp(), CUR_USER);
SELECT cityId FROM city WHERE city = CUST_CITY AND countryId = ccountryId
INTO ccityId;
END;
END IF;
IF (SELECT addressId FROM address WHERE address = CUST_ADDRESS AND address2 = CUST_ADDRESS2 AND phone = CUST_PHONE AND cityId = ccityId) IS NOT NULL THEN
BEGIN
SELECT addressID FROM address WHERE address = CUST_ADDRESS AND address2 = CUST_ADDRESS2 AND phone = CUST_PHONE AND cityId = ccityID 
INTO caddressId;
END;
ELSE BEGIN
INSERT INTO address (address, address2, cityId, postalCode, phone, createDate, createdBy, lastUpdate, lastUpdateby)
VALUES (CUST_ADDRESS, CUST_ADDRESS2, ccityId, CUST_ZIP, CUST_PHONE, current_date(), CUR_USER, current_timestamp(), CUR_USER);
SELECT addressId FROM address WHERE address = CUST_ADDRESS AND address2 = CUST_ADDRESS2 AND phone = CUST_PHONE AND cityId = ccityID 
INTO caddressId;
END;
END IF;
UPDATE customer 
SET customerName = CUST_NAME, addressId = caddressId, active = 1, lastupdate = current_timestamp(), lastUpdateBy = CUR_USER
WHERE customerId = CUST_ID;
END;
ELSE BEGIN
SELECT * FROM customer WHERE customerId = CUST_ID;
END;
END IF;
END
IF (SELECT cityId FROM city WHERE city = CUST_CITY AND countryId = ccountryId) IS NOT NULL THEN 
BEGIN SELECT cityId FROM city WHERE city = CUST_CITY AND countryId = ccountryId INTO ccityId; 
END; 
ELSE BEGIN INSERT INTO city (city, countryId, createDate, createdBy, lastUpdate, lastUpdateBy) 
VALUES (CUST_CITY, ccountryId, current_date(), CUR_USER, current_timestamp(), CUR_USER); 
SELECT cityId FROM city WHERE city = CUST_CITY AND countryId = ccountryId INTO ccityId; 
END; 
END IF; 
IF (SELECT addressId FROM address WHERE address = CUST_ADDRESS AND address2 = CUST_ADDRESS2 AND phone = CUST_PHONE AND cityId = ccityId) IS NOT NULL THEN 
BEGIN SELECT addressID FROM address WHERE address = CUST_ADDRESS AND address2 = CUST_ADDRESS2 AND phone = CUST_PHONE AND cityId = ccityID INTO caddressId; 
END; 
ELSE 
BEGIN INSERT INTO address (address, address2, cityId, postalCode, phone, createDate, createdBy, lastUpdate, lastUpdateby) 
VALUES (CUST_ADDRESS, CUST_ADDRESS2, ccityId, CUST_ZIP, CUST_PHONE, current_date(), CUR_USER, current_timestamp(), CUR_USER); 
SELECT addressId FROM address WHERE address = CUST_ADDRESS AND address2 = CUST_ADDRESS2 AND phone = CUST_PHONE AND cityId = ccityID INTO caddressId; 
END; 
END IF; 
UPDATE customer 
SET customerName = CUST_NAME, addressId = caddressId, active = 1, lastupdate = current_timestamp(), lastUpdateBy = CUR_USER WHERE customerId = CUST_ID; 
END; 
ELSE 
BEGIN 
SELECT * FROM customer WHERE customerId = CUST_ID; 
END; 
END IF; 
END

1 个答案:

答案 0 :(得分:1)

要解决您的错误,您应该了解当您使用子查询并将结果与​​单个值进行比较时,子查询必须返回标量。

错误在于:

IF (SELECT * FROM customer WHERE customerId = CUST_ID) IS NOT NULL THEN

我假设SELECT *如何返回多列,是否在`IS NOT NULL表达式中?测试了多列中的哪一列为空?

SQL支持元组比较,如下所示:

(column1, column2, column3) = (1, 2, 3)

但有些比较操作不支持此格式,例如LIKEIS NOT NULL。对于那些,您必须在比较的左侧只使用一列。

有关详细信息,请参阅https://dev.mysql.com/doc/refman/5.7/en/scalar-subqueries.html

使用EXISTS (subquery)而不是(subquery) IS NOT NULL会更清楚。

IF EXISTS (SELECT * FROM ...) THEN
    ...

然后你在select-list中放入什么并不重要,MySQL无论如何都会忽略它,因为它只关心是否存在一行或多行,而不是它们返回的行。见https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html

除了这个错误,我还有一些关于你的代码的评论:

  • 您不需要这么多BEGIN ... END块。 IF THEN ELSE END IF语法已经支持多个语句的块。请参阅https://dev.mysql.com/doc/refman/5.7/en/if.html

  • 代码缩进和格式化对于帮助您发现逻辑错误非常重要。

  • 您似乎正在使用UPDATE,就像它支持ELSE子句一样。也许你的意思是“如果它不匹配任何行,那么做其他事情”?这是个错误。 UPDATE没有此功能。

    您可能希望使用ROW_COUNT() function来测试 如果UPDATE改变了什么。

  • 有几次使用SELECT...INTO来捕获刚刚由前一个INSERT生成的自动增量ID。这样做会更简单:

    SET ccountryId = LAST_INSERT_ID();
    

    该函数始终返回最近生成的自动增量ID,如果有其他并发会话执行自己的插入,则可以安全使用。请参阅LAST_INSERT_ID() function上的手册以阅读相关内容。