簡體   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