【问题标题】:MySQL Cursor Loop does not updateMySQL 游标循环不更新
【发布时间】:2013-07-12 14:01:30
【问题描述】:

对于我编写的 MySQL 存储过程的帮助,我将不胜感激。它在 Windows 上的 MySQL 5.6.11 上运行,我已经阅读并重新阅读了 MySQL 文档并进行了一些谷歌搜索。

背景

我有用于存储与产品相关的信息的数据库,在某些情况下,我想通过从一个产品记录复制并插入另一个产品记录或从一个产品记录并插入特定产品的所有产品记录来创建新的关联信息团体。我可以成功地从一个产品记录复制并插入另一个产品记录,但我无法从一个产品记录复制然后插入特定产品组中的所有产品记录。

初步研究表明,将游标作为存储过程的一部分可以提供解决方案。就问题而言,我有两个表涉及,一个项目符号,它包含项目符号点,我想复制它们。第二个表是主表,它保存产品数据,如产品代码和与产品代码关联的产品组代码。

我希望通过以下方式在项目符号表中创建新记录:

  • 检索特定产品代码的项目符号记录,用于 例如,对于产品代码 10001,我有 4 个项目符号记录。
  • 然后我想为产品组选择所有产品,例如有81个 产品组 3 中的产品代码。
  • 然后,对于产品组 3 中的每个产品代码,我想为每个项目符号创建一个新记录。

这意味着将向 bulets 表添加 81 x 4 条新记录。

注意我正在使用 LibreOffice Base、表单和宏来与 MySQL 交互。

我做了什么

我发现我可以使用以下语句进行一对一的复制:

INSERT INTO bullets (product_code, bullet_text) SELECT 'fromCode', bullet_text
FROM bullets WHERE product_code = 'toCode'

其中 fromCode 和 toCode 由 LibreOffice Base 表单提供并使用 LibreOffice BASIC 脚本进行处理,这一切正常。希望我没有提供太多多余的信息。

所以我的想法是我可以编写一个存储过程,使用游标来获取特定产品组的产品代码,然后遍历产品代码来写入我的新记录。下面是存储过程:

BEGIN
    DECLARE product_code_from_group VARCHAR(30);
    DECLARE from_product_code VARCHAR(30);
    DECLARE done INT DEFAULT FALSE;
    DECLARE cur_get_product_codes CURSOR FOR
        SELECT product_code FROM master
        WHERE product_group = to_product_group ;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;

    OPEN cur_get_product_codes;

    copybullets: LOOP
        FETCH cur_get_product_codes INTO product_code_from_group;
    IF done THEN
        CLOSE cur_get_product_codes;
        LEAVE copybullets;
    END IF;

    INSERT INTO bullets (product_code, bullet_text) 
    SELECT product_code_from_group, bullet_text 
    FROM bullets
    WHERE product_code = from_product_code;

    END LOOP;

    CLOSE cur_get_product_codes;

END

当我执行时,它似乎正在运行,但没有创建新记录。我正在测试它使用

 CALL copy_bullets_test(10001,3)
  • 10001 是我从中获取项目符号的代码
  • 3 是我用于获取产品列表的产品组。

我很确定问题在于我的知识有限,我已经仔细阅读了 Roland Boumans 博客上的复制代码,但我一定遗漏了一些东西。看起来我的代码没有通过循环进行迭代,但我不知道为什么。

【问题讨论】:

    标签: mysql sql loops stored-procedures cursor


    【解决方案1】:

    如果我理解正确,您只需要CROSS JOIN。试试

    INSERT INTO bullets (product_code, bullet_text) 
    SELECT m.product_code, b.bullet_text 
      FROM bullets b CROSS JOIN master m
     WHERE b.product_code = 10001
       AND m.product_group = 3
       AND m.product_code <> 10001;
    

    这里是 SQLFiddle 演示。

    现在你可以把它包装成一个存储过程,如果你去

    CREATE PROCEDURE copy_bullets_test (IN product_code_from INT, IN product_group_to INT)
    INSERT INTO bullets (product_code, bullet_text) 
    SELECT m.product_code, b.bullet_text 
      FROM bullets b CROSS JOIN master m
     WHERE b.product_code = product_code_from
       AND m.product_group = product_group_to
       AND m.product_code <> product_code_from;
    

    并使用它

    CALL copy_bullets_test(10001, 3);
    

    这里是 SQLFiddle 该案例的演示。

    【讨论】:

    • 嗨,彼得,谢谢,这正是我想要的,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多