0

我正在 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
4

1 回答 1

1

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

错误在这里:

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

SELECT *假设返回多个列的 `IS NOT NULL 表达式如何?对许多列中的哪一列进行了空值测试?

SQL 确实支持这样的元组比较

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

但是有些比较操作不支持这种格式,例如LIKEor IS 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
    ...

那么不管你在选择列表中放了什么,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() 函数来测试 UPDATE 是否更改了任何内容。

  • 多次SELECT...INTO用于捕获刚刚由前面的INSERT. 这样做会更简单:

    SET ccountryId = LAST_INSERT_ID();
    

    该函数始终返回最近生成的自动增量 id,如果有其他并发会话进行自己的插入,则使用它是安全的。请参阅有关LAST_INSERT_ID() 函数的手册以了解它。

于 2018-02-03T18:26:01.070 回答