【发布时间】:2020-08-04 18:51:01
【问题描述】:
我在下面有一个简单的 mysql 过程,可以根据传递的参数从表中删除数据。 由于未删除依赖数据,我收到外部约束失败异常。 我正在形成要删除的 ID 列表,因为我想避免对表进行全表扫描 使用子查询时。 任何帮助表示赞赏。
CREATE PROCEDURE `deleteService`(IN serviceID LONG)
BEGIN
DECLARE rpslist varchar(512) DEFAULT "";
DECLARE finished INTEGER DEFAULT 0;
DECLARE rpsid varchar(512) DEFAULT "";
DECLARE rpsidcursor
CURSOR FOR
select id from rpsa where so_id in (select id from rpso where rps_id = serviceID);
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
OPEN rpsidcursor; //fetch ids to delete
getRPSId: LOOP
FETCH rpsidcursor INTO rpsid;
IF finished = 1 THEN
LEAVE getRPSId;
END IF;
SET rpsid = concat("'",rpsid,"'"); -- form concatenated string of IDs
SET rpslist = CONCAT(rpsid,",",rpslist);
END LOOP getRPSId;
CLOSE rpsidcursor;
SET rpslist = substring(rpslist,1,length(rpslist) -1); -- remove last comma
DELETE from uach where rpsa_id in (rpslist); -- delete dependent data . forming the list to hit index
-- this statement fails bcos the delete above did not work and there is foreign constraint
DELETE from rpsa where rpselectedso_id in (select id from rpselectedso where rpaxnservice_id = serviceID);
END
【问题讨论】:
-
为什么要使用游标并将 ID(我假设为整数类型)连接到字符串?为什么你不能把你的 ID 放到一个临时表中并在你的 delete 语句中使用它?如果您试图避免表扫描,那么您的索引是错误的。
-
WHERE .. IN (...)需要一个字符串文字列表(许多参数文字用逗号分隔),而rpslist是一个带有 CSV 的字符串文字。请改用WHERE FIND_IN_SET(rpsa_id, rpslist)。 -
我已经尝试了上述两种方法,并且在这两种情况下它都会进行全表扫描。索引在 id rpsa_id 列上正确定义。在本地工作而不是在有百万多行的产品中工作。
标签: mysql