我是MySQL的新手。
我正在开发一个系统,其中许多用户被分配了特定的任务。当他们在一段时间内处于非活动状态(比如说超过10分钟)时,我希望系统自动清除他们的分配,以便其他人可以处理它们。
为此,我创建了一个名为 tblactivitytracker 的表格来进行活动跟踪。分配位于名为 tblinquiries 的表中。我创建了一个存储过程来获取非活动用户。
这是一个sqlfiddle示例:Get Inactive Users
在上面的示例中,我获得了3个非活动用户:audit1,audit2和audit3。
我创建了一个存储过程来清除单个用户的工作分配,从而完美地完成了工作。
CREATE PROCEDURE `spClearAssignedInquiry`(IN `pAssignedTo` VARCHAR(50))
UPDATE
tblinquiries
SET
AuditStatus='Check', AssignedTo=NULL, Result=NULL,
ResultCategories=NULL, AuditBy=NULL,
Remarks=NULL, StartTime=NULL, EndTime=NULL
WHERE
AssignedTo=pAssignedTo AND
AuditStatus='Assigned' AND EndTime IS NULL
如果在上述过程中将audit1作为参数传递,它将清除用户的分配。
要一次通过所有不活动的用户并清除分配,我按照this stackoverflow solution尝试了以下过程:
CREATE PROCEDURE `spInactiveUsers`()
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE AssignedTo VARCHAR(50);
DECLARE cur CURSOR FOR
SELECT
q1.AssignedTo AS AssignedTo
FROM
(SELECT
InquiryId, AssignedTo
FROM
tblinquiries
WHERE
AuditStatus='Assigned' AND StartTime IS NOT NULL AND EndTime IS NULL
ORDER BY
AssignedTo ASC
) q1
RIGHT JOIN
(SELECT
UserId, MAX(LastActivity) AS LastActivity, ROUND(TIME_TO_SEC(TIMEDIFF(MAX(LastActivity),CURRENT_TIMESTAMP()))/60,0) AS InactiveMinutes
FROM
tblactivitytracker
GROUP BY
UserId
ORDER BY
LastActivity ASC
) q2
ON
q2.UserId=q1.AssignedTo
WHERE
q2.InactiveMinutes>10;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
OPEN cur;
testLoop: LOOP
FETCH cur INTO AssignedTo;
IF done THEN
LEAVE testLoop;
END IF;
CALL spClearAssignedInquiry(AssignedTo);
END LOOP testLoop;
CLOSE cur;
END
但是它不会清除任何分配。
最近几天,我把头撞在墙上。任何帮助将非常感激。提前致谢。
答案 0 :(得分:1)
您正在使用的变量名也是列名。变量的值将优先于列的值,请参见the documentation:
局部变量不应与表列具有相同的名称。如果一个SQL语句(例如SELECT ... INTO语句)包含对列的引用和具有相同名称的声明的局部变量,则MySQL当前会将引用解释为变量的名称。
所以在
...
FROM
(SELECT
InquiryId, AssignedTo
...
您正在选择变量AssignedTo
(即null
),而不是表中的列。
只需将其重命名(在declare
和循环中),或者不建议使用,则显式声明表名以设置范围,例如SELECT InquiryId, tblinquiries.AssignedTo .... order by tblinquiries.AssignedTo
。
还有另一个(次要)问题是您在TIMEDIFF(MAX(LastActivity), CURRENT_TIMESTAMP())
中使用TIMEDIFF。如果要获得正数(如q2.InactiveMinutes>10
),则需要在第一个参数中使用较晚的时间。