我需要清理users表和几个相关的表。所以我创建了一个包含userids的变量,我想使用这些值,而不是对每个delete语句使用子查询。
我的语法错误。我做错了什么?
DELIMITER $$
CREATE PROCEDURE `DBNAME`.`SP_PURGE_DISABLED_USERS` ()
BEGIN
select userid into @disabled_users from USERS where disabled=1;
delete from USER_ACTIVITY where userid in SELECT userid FROM @disabled_users;
delete from USER_PREFS where userid in SELECT userid FROM @disabled_users;
-- <snip> several other related tables to be cleaned up
delete from USERS where userid in SELECT userid FROM @disabled_users;
END
答案 0 :(得分:0)
首先,在程序结束时,您需要设置分隔符:
END$$
然后将分隔符重置为;
DELIMITER ;
在此过程中,您的删除语句没有意义。我将停止使用参数来存储select和内部选择的结果:
delete from USER_ACTIVITY
WHERE userid in ( select userid from users where disabled=1 );
如果你只有一小部分要删除的禁用用户,你可以使用group concat并在set中找到:
DELIMITER $$
CREATE PROCEDURE `DBNAME`.`SP_PURGE_DISABLED_USERS` ()
BEGIN
select GROUP_CONCAT(userid) into @disabled_users from USERS where disabled=1;
delete from USER_ACTIVITY where FIND_IN_SET(userid, @disabled_users);
delete from USER_PREFS where FIND_IN_SET(userid, @disabled_users);
-- <snip> several other related tables to be cleaned up
delete from USERS where FIND_IN_SET(userid, @disabled_users);
END$$
DELIMITER ;
我不会对成千上万的用户ID执行此操作...但变量中的字符串长度可能有限制。
答案 1 :(得分:0)
我决定带一张临时桌子。它将存储过程执行时间减半。
CREATE PROCEDURE `DBNAME`.`SP_PURGE_DISABLED_USERS` ()
BEGIN
create temporary table disabled_users
as (select userid from USERS where disabled=1);
delete from USER_ACTIVITY where userid in SELECT userid FROM disabled_users;
delete from USER_PREFS where userid in SELECT userid FROM disabled_users;
-- <snip> several other related tables to be cleaned up
delete from USERS where userid in SELECT userid FROM disabled_users;
drop table disabled_users;
END
感谢所有帮助解决这个问题的人。