MySQL存储过程像光标声明中的合成文件一样

时间:2017-08-16 08:01:58

标签: mysql stored-procedures

对于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';

哪个也行不通。在debuggin期间,我还尝试使用这样的特定日期:

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

一切都很顺利,但显然只是测试并查看在游标声明中WHERE cluase语法是否正确。

我迷失在这里,并希望得到你们的一些帮助。

提前谢谢你。

2 个答案:

答案 0 :(得分:1)

您已经很好地调试了代码,并且您已成功隔离了问题。它不是using UnityEngine; using System.Collections; using System.IO; using UnityEditor; using System; //This allows the IComparable Interface using System.Collections.Generic; public class Words : MonoBehaviour { public List<string> wordslist = new List<string>(); static void WriteString() { string path = "Assets/Resources/words.txt"; //Write some text to the test.txt file StreamWriter writer = new StreamWriter(path, true); writer.WriteLine("Test"); writer.Close(); //Re-import the file to update the reference in the editor AssetDatabase.ImportAsset(path); TextAsset asset = (TextAsset)Resources.Load("words"); //Print the text from the file Debug.Log(asset.text); } static void ReadString() { string text = " "; string path = "Assets/Resources/words.txt"; //List<WordsList> wordslist = new List<WordsList>(); int ix = 1; //Read the text from directly from the test.txt file StreamReader reader = new StreamReader(path); while(text != null){ text = reader.ReadLine(); if (text != null) { wordslist.Add (text); ix++; Debug.Log (wordslist[ix].ToString()); } } //Debug.Log (reader.ReadToEnd ().Length); //Debug.Log(reader.ReadToEnd()); reader.Close(); } public void GetWord(){ ReadString (); } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } } 本身,也不是存储过程绊倒你的事实。

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

解决方案:放弃@(在@上):

comp_date

假设会话变量未设置,我相信您将获得WHERE `date` LIKE CONCAT('%', comp_date, '%'); ,但这不会起作用。这就是你所看到的症状。

对于另一个问题,我们有一些有用的解释:MySQL: @variable vs. variable. Whats the difference?

答案 1 :(得分:0)

我发现了问题,原来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来计算前导零。