【问题标题】:MySQL: Run a stored procedure getting parameter from a query inside another stored procedureMySQL:运行存储过程从另一个存储过程中的查询获取参数
【发布时间】:2018-07-15 05:00:11
【问题描述】:

我是 MySQL 新手。

我正在开发一个系统,其中许多用户被分配到特定任务。当他们在一段时间内不活动时(比如说超过 10 分钟),我希望系统自动清除他们的任务,以便其他人可以处理它们。

为了实现这一点,我创建了一个名为 tblactivitytracker 的表来进行活动跟踪。分配位于名为 tblinquiries 的表中。我创建了一个存储过程来获取非活动用户。

这是一个 sqlfiddle 示例:Get Inactive Users

在上面的示例中,我得到了 3 个非活动用户:auditor1、auditor2 和 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

但它并没有清除任何分配。

在过去的几天里,我一直在用头撞墙。任何帮助将非常感激。提前致谢。

【问题讨论】:

标签: mysql stored-procedures


【解决方案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)。

【讨论】:

  • 非常感谢!我重命名了变量,就成功了。
猜你喜欢
  • 2018-03-04
  • 1970-01-01
  • 2011-05-05
  • 2011-04-26
  • 2013-10-10
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
相关资源
最近更新 更多