Nested Cursors in Mysql

后端 未结 3 1284
灰色年华
灰色年华 2020-12-24 03:08

I have three tables.
Project(Id), attribute(Id), project_attribute(Id, project_id, attribute_id).

I want to create records in project_at

相关标签:
3条回答
  • 2020-12-24 03:19

    Try this, this will surely solve your issue.

    DELIMITER $$
    CREATE DEFINER=`root`@`localhost` PROCEDURE `proj_attr`()
    BEGIN   
        DECLARE proj_done, attribute_done BOOLEAN DEFAULT FALSE;    
        declare attributeId int(11) default 0;
        declare  projectId int(11) default 0;
        DECLARE curProjects CURSOR FOR SELECT id FROM project order by id;  
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET proj_done = TRUE;
    
        OPEN curProjects;
        cur_project_loop: LOOP
        FETCH FROM curProjects INTO projectId;
    
            IF proj_done THEN
            CLOSE curProjects;
            LEAVE cur_project_loop;
            END IF;
    
            BLOCK2: BEGIN
            DECLARE curAttribute CURSOR FOR SELECT id FROM attribute order by id;
            DECLARE CONTINUE HANDLER FOR NOT FOUND SET attribute_done = TRUE;
            OPEN curAttribute; 
            cur_attribute_loop: LOOP
            FETCH FROM curAttribute INTO attributeId;   
                IF proj_done THEN
                set proj_done = false;
                CLOSE curAttribute;
                LEAVE cur_attribute_loop;
                END IF; 
                insert into project_attribute_value(project_id, attribute_id)
                    values(projectId, attributeId); 
            END LOOP cur_attribute_loop;
            END BLOCK2;
        END LOOP cur_project_loop;
    
    
        END$$
    
    DELIMITER ;
    
    0 讨论(0)
  • 2020-12-24 03:19

    Quite bluntly, nested cursors are (usually) a terrible idea. You can get what you want directly, without using a cursor, by using a normal CROSS JOIN.

    INSERT INTO proj_attr (project, attribute)
        SELECT p.id AS projectid, a.id AS attributeid
        FROM project p CROSS JOIN attribute a;
    
    0 讨论(0)
  • 2020-12-24 03:39

    After the first iteration within the inner cursor "attribute_done" variable is set to "true". And it remains "true" for every next iterations.

    This causes every next iterations to skip the inner loop.

    A sample nested cursor is illustrated below.


    CREATE TABLE `parent` (
      `a` int(11) DEFAULT NULL
    ) ENGINE=InnoDB
    CREATE TABLE `child` (
      `a` int(11) DEFAULT NULL,
      `b` varchar(20) DEFAULT NULL
    ) ENGINE=InnoDB
    
    insert into parent values (1),(2),(3);
    
    insert into child values (1,'a'),(1,'b'),(2,'a'),(2,'b'),(3,'a'),(3,'b');
    
    ----------------------------------
    drop procedure if exists nestedCursor;
    create procedure nestedCursor()
    BEGIN   
        DECLARE done1, done2 BOOLEAN DEFAULT FALSE;  
        DECLARE parentId,childId int;
        DECLARE childValue varchar(30);
    
        DECLARE cur1 CURSOR FOR SELECT a FROM parent;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done1 = TRUE;
    
        open cur1;
        loop1: LOOP
        FETCH FROM cur1 INTO parentId;
        IF done1 THEN
            CLOSE cur1;
            LEAVE loop1;
        END IF;
    
        BLOCK1 : BEGIN
        DECLARE cur2 CURSOR FOR SELECT a,b FROM child where a = parentId;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done2 = TRUE;
    
    
        open cur2;
        loop2 : LOOP
        FETCH FROM cur2 INTO childId,childValue;  
            if done2 THEN
            CLOSE cur2;
            SET done2 = FALSE;
            LEAVE loop2;
            end if;
            select parentId,childId,childValue;
    
        END LOOP loop2;
        END BLOCK1;
        END loop loop1;
    END;
    
    0 讨论(0)
提交回复
热议问题