2017-11-20 1 views
1

Ich schreibe ein sehr einfaches Programm, um die Position INT-Spalte in der "Todo" -Tabelle für vorhandene Zeilen zu aktualisieren. Das Ziel besteht darin, den Standortwert schrittweise für jeden Benutzer festzulegen, beginnend bei 0. Wenn der Code ausgeführt wird, scheint er nur den endgültigen Wert für die Schleife jedes Benutzers zu erfassen. Gibt es etwas, dass ich die Variablen von MySQL falsch verstehe? Oder vielleicht habe ich die Schleifen vermasselt.MySQL Stored Procedure Schleife Inkrementieren Wert, nur den endgültigen Wert

Dies war eine späte Nacht>. <

BEGIN 
    DECLARE loop_done INT DEFAULT 0; 
    DECLARE current_user_id INT; 
    DECLARE current_todo_id INT; 
    DECLARE todo_position INT DEFAULT 0; 
    DECLARE cur_users CURSOR FOR 
     SELECT id FROM users; 
    DECLARE cur_todos CURSOR FOR 
     SELECT id FROM todo WHERE user_id = @uid; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET loop_done = 1; 

    OPEN cur_users; 
    loop_users: LOOP 

     FETCH cur_users INTO current_user_id; 

     IF loop_done = 1 THEN 
      SET loop_done = 0; 
      LEAVE loop_users; 
     END IF; 

     SET @uid = current_user_id; 
     SET todo_position = 0; 

     OPEN cur_todos; 

     loop_todos: LOOP 
      FETCH cur_todos INTO current_todo_id; 
      IF loop_done = 1 THEN 
       SET loop_done = 0; 
       SET todo_position = 0; 
       LEAVE loop_todos; 
      END IF; 

      UPDATE todo SET position = todo_position WHERE user_id = @uid; 
      SET todo_position = todo_position + 1; 

     END LOOP loop_todos; 

     CLOSE cur_todos; 

    END LOOP loop_users; 
END$$ 

Hier sind die tatsächlichen Ergebnisse:

+----------+ 
| position | 
+----------+ 
|  3 | 
|  3 | 
|  3 | 
|  3 | 
|  4 | 
|  4 | 
|  4 | 
|  4 | 
|  4 | 
+----------+ 

Dies sind die erwarteten Ergebnisse:

+----------+ 
| position | 
+----------+ 
|  0 | 
|  1 | 
|  2 | 
|  3 | 
|  0 | 
|  1 | 
|  2 | 
|  3 | 
|  4 | 
+----------+ 
+1

die gleiche Prozedur für beide Schleifen zu haben, ist keine gute Idee, –

+0

Wechsel: 'UPDATE \' todo \ 'SET \' Position \ '= \ 'todo_position \' WHERE \ user_id \ '= @ \ uid \'; '. von 'UPDATE \ 'todo \' SET \' position \ '= \' todo_position \ 'WHERE \ 'id \' = \ 'current_todo_id \'; ' – wchiquito

Antwort

1

Ich glaube nicht, Sie Cursor, um alle auf zum Beispiel

drop table if exists todo; 

create table todo (id int, user_id int, position int); 

truncate table todo; 
insert into todo values (1,1,null),(2,1,null),(2,2,null); 


update todo t join (
      select id,user_id, 
      if(user_id <> @p,@rn:=0,@rn:[email protected]+1) rn , 
      @p:=user_id p 
      from todo, (select @rn:=0,@p:=0) r 
      order by user_id,id 
      ) s on s.id = t.id and s.user_id = t.user_id 
    set position = s.rn 

    where 1 = 1; 

Simulat es Zeilennummer Funktionen in anderen dbs fand eine Variable und gibt

select * from todo; 

+------+---------+----------+ 
| id | user_id | position | 
+------+---------+----------+ 
| 1 |  1 |  0 | 
| 2 |  1 |  1 | 
| 2 |  2 |  0 | 
+------+---------+----------+ 
3 rows in set (0.02 sec) 
+0

Arbeitete wie ein Charme und viel ausdrucksvoller. Vielen Dank. – Firephp

Verwandte Themen