繁体   English   中英

游标声明中的MySQL存储过程LIKE语法

[英]MySQL Stored Procedure LIKE syntaxt in Cursor Declaration

关于MySQL存储过程,我非常环保,在选择当月收到的所有付款并循环浏览以查看哪些帐户未支付月费时遇到了麻烦,我的问题似乎出在LIKE语句上在游标的声明中。 这是代码:

CREATE DEFINER=`wisper`@`%` PROCEDURE `process_rejections`()
BEGIN
    DECLARE cursor_ID INT(11);
    DECLARE account_id INT(11);
    DECLARE amount_paid DECIMAL(10,2);
    DECLARE date_paid DATETIME;
    DECLARE cur_year INT DEFAULT (SELECT YEAR(CURRENT_DATE()));
    DECLARE cur_month INT DEFAULT (SELECT MONTH(CURRENT_DATE()));
    DECLARE comp_date VARCHAR(10) DEFAULT (SELECT CONCAT(cur_year,'-',cur_month));
    DECLARE done INT DEFAULT FALSE;

    DECLARE cursor_i CURSOR FOR 
    SELECT `id`, `account_id`, `amount_paid`, `date` 
    FROM `payments_received` 
    WHERE `date`LIKE CONCAT('%',@comp_date,'%');

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN cursor_i;
    read_loop: LOOP
        FETCH cursor_i INTO cursor_ID, account_id, amount_paid, date_paid;
            IF done THEN
                LEAVE read_loop;
            END IF;
            //Do Stuff here like change the status of the account
        END LOOP;
    CLOSE cursor_i;
END

如果我删除此:

WHERE `date` LIKE CONCAT('%',@comp_date,'%');

一切正常,但显然选择的是*收到的付款,而不是例如在2017年8月期间发生的付款。我不想选择*,因为随着时间的流逝,特定表中将有成千上万的行,而我不希望开销变得太多。 我也对此进行了测试:

WHERE `date` LIKE '2017-08-11';

这也行不通。 在调试期间,我还尝试使用如下指定日期:

WHERE `date` = '2017-08-11';

一切工作都很好,但是显然只是为了测试并查看WHERE语句在游标声明中在语法上是否正确。

我在这里迷路了,希望你们能提供一些帮助。

先感谢您。

您已经很好地调试了代码,并且成功隔离了问题。 这不是LIKE本身,也不是它是使您绊倒的存储过程。

问题 :您使用的是会话变量(该变量前面带有@ ),而不是前面几行声明的存储过程变量。

解决方案 :删除@ (在comp_date ):

WHERE `date` LIKE CONCAT('%', comp_date, '%');

假设未设置会话变量,我相信您会得到NULL ,它将无法正常工作。 因此,您所看到的症状。

关于另一个SO问题,这里有一些有用的解释: MySQL:@variable vs.variable。 有什么不同?

我发现了问题,原来comp_date看起来像是2017-8,而不是像2017-08这样使用前导零,这是完成的代码:

PS:是的,我觉得自己很傻,因为没有测试我在声明中提交的值,但是也许其他人也为此感到挣扎,这可以帮助他们。

CREATE DEFINER=`wesley`@`%` PROCEDURE `process_rejections`()
BEGIN
    DECLARE cursor_ID INT(11);
    DECLARE account_id INT(11);
    DECLARE amount_paid DECIMAL(10,2);
    DECLARE date_paid DATETIME;

    DECLARE comp_date VARCHAR(10) DEFAULT 
    CONCAT(YEAR(CURRENT_DATE()), '-', LPAD(MONTH(CURRENT_DATE()), 2, '0'));

    DECLARE done INT DEFAULT FALSE;
    DECLARE cursor_i CURSOR 
    FOR SELECT `id`, `account_id`, `amount_paid`, `date` 
    FROM `payments_received` 
    WHERE `date` 
    LIKE CONCAT('%', comp_date,'%');

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cursor_i;
    read_loop: LOOP
    FETCH cursor_i INTO cursor_ID, account_id, amount_paid, date_paid;
            IF done THEN
                LEAVE read_loop;
            END IF;
        //Do stuff here like changing account status
        END LOOP;
    CLOSE cursor_i;
END

请注意我如何声明comp_date以解释前导零。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM