存储过程只插入一次数据

Posted

技术标签:

【中文标题】存储过程只插入一次数据【英文标题】:Stored Procedure Inserts Data Just Once 【发布时间】:2020-02-09 04:42:18 【问题描述】:

我一直在尝试创建一个存储过程来使用客户的有效日期和有效日期来填充日历表。为了将它们映射到各自的记录,它们被日历表中的外键绑定。

现在,在他们成功注册并创建记录后立即调用存储过程。但是,存储过程只成功运行一次。第一次运行后,不会为后续客户端创建任何记录。

这是存储过程:

CREATE DEFINER=`root`@`localhost` PROCEDURE `fillGroomerCalendar`(IN `dateStart` DATE, IN `dateEnd` DATE, IN `groomerID` INT)
BEGIN
DECLARE adate date;
    START TRANSACTION;
    WHILE dateStart <= dateEnd DO
        SET adate = (SELECT groomerDate FROM groomer_calendar WHERE groomerDate = dateStart);
        IF adate IS NULL THEN BEGIN
            INSERT INTO groomer_calendar (groomerID, groomerDate, groomerDateStatus) VALUES (groomerID, dateStart, "Open");
        END; END IF;
        SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
    END WHILE;
    COMMIT;
END

感谢任何帮助理解为什么在第一次成功运行后失败。

P.S.:我已检查表上是否存在导致下一次运行被阻止的锁。但是没有表被锁定。

更新:

根据尼克的评论和他在下面发布的答案,这是更正的过程代码。如果其他人遇到类似问题,这可能会帮助他们找到解决方案。

CREATE DEFINER=`root`@`localhost` PROCEDURE `fillGroomerCalendar`
    (IN `dateStart` DATE, IN `dateEnd` DATE, IN `inGroomerID` INT)
BEGIN
DECLARE adate date;
    START TRANSACTION;
    WHILE dateStart <= dateEnd DO
        SET adate = (SELECT groomerDate FROM groomer_calendar 
            WHERE groomerDate = dateStart AND groomerID = inGroomerID);
        IF adate IS NULL THEN BEGIN
            INSERT INTO groomer_calendar (groomerID, groomerDate, groomerDateStatus) 
                VALUES (inGroomerID, dateStart, "Open");
        END; END IF;
        SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
    END WHILE;
    COMMIT;
END

【问题讨论】:

我怀疑SELECT groomerDate FROM groomer_calendar WHERE groomerDate = dateStart 应该是SELECT groomerDate FROM groomer_calendar WHERE groomerDate = dateStart AND groomerID = in_groomerID(注意您需要更改输入变量的名称以避免名称冲突) @Nick,请原谅我的语言,但我的天哪!!!!做到了。如果您可以发表您的评论作为答案,我将很高兴接受它。这无疑为我节省了一些时间。 :-) 【参考方案1】:

您的问题是您没有根据特定的groomerID 值检查表中的日期,因此当您下次运行具有相似日期的过程时,adate 不是NULL,因为之前的插入。因此,您需要将groomerID 的测试添加到SELECTadate。但是,您还有第二个问题,因为您的列名与您的参数名匹配,因此尝试使用 WHERE groomerID = groomerID 将导致同样的问题。您可以将参数名称更改为例如in_groomerID 来解决这个问题。所以这应该是你的查询:

SET adate = (SELECT groomerDate
             FROM groomer_calendar
             WHERE groomerDate = dateStart
               AND groomerID = in_groomerID);

【讨论】:

以上是关于存储过程只插入一次数据的主要内容,如果未能解决你的问题,请参考以下文章

sql server中怎么把一个表的数据全部插入到另一个表,每次1000条的插入,一次执行,不要在存储过程里改的

存储过程返回2个结果数据集 - 有没有办法只将第一个数据集插入变量但仍然显示第二个?

限制最终用户使用存储过程插入数据

存储过程 CRUD MySQL

SQL存储过程如何调用存储过程?

插入选择存储过程不起作用插入NULL