2015-05-11 2 views
0

Я пытаюсь написать хранимую процедуру в MySQL, где мне нужно зациклиться на курсоре, и выполнить инструкцию SQL, которая использует кусок данных из курсора, который извлекается в переменную, а затем выполняется как SQL. Курсор orders_cur сортируется по this_addr; в данном блоке данных this_addr первая запись пропущена, а остальная часть должна быть помечена установкой duplicateorder = "1".Почему MySQL находит ошибку в заявлении CONCAT?

По некоторым причинам, я не могу получить строку с помощью функции CONCAT работать, не давая мне ошибку:

  OPEN orders_cur; 
      order_loop: LOOP 
       -- Now loop on orders_cur until this_addr = match_addr 
       find_addr_loop: REPEAT 
        FETCH orders_cur INTO this_addr,this_orderid; 
       UNTIL this_addr = match_addr 
       END REPEAT; 
       -- Skip the first order that matched by performing another fetch 
       FETCH orders_cur INTO this_addr,this_orderid; 
       -- Now start next loop which does the real work; set duplicateorder on the remaining records in cursor, 
       -- using the orders_cur.order_id to locate the actual record in the Reservations table. 
       set_dupe_loop: WHILE this_addr = match_addr 
        SET @sql = CONCAT('UPDATE Reservations SET duplicateorder = \'1\' WHERE order_id=',this_orderid); 
        PREPARE runme FROM @sql; 
        EXECUTE runme; 
        FETCH orders_cur INTO this_addr,this_orderid; 
       END WHILE set_dupe_loop:; 
       DEALLOCATE PREPARE runme; 
      END LOOP order_loop; 

Я пробовал все изменения можно на побег литералы, что мне нужно вокруг «1» но безрезультатно, и я собираюсь косоглазый ... если кто-нибудь увидит, где моя ошибка лежит, я бы очень признателен ...

--rixter

+1

Из любопытства, что такое DECLARE для 'this_orderid'? Изменить: Nevermind, вероятно, см. Ответ ниже. – Uueerdo

ответ

1

Вам не нужен курсор для этой операции. Вы можете:

UPDATE Reservations r JOIN 
     (SELECT this_addr, MIN(order_id) as minoi 
     FROM Reservations r2 
     WHERE this_addr = match_addr 
     GROUP BY this_addr 
     ) dups 
     ON r.this_addr = dups.this_addr and r.order_id > dups.minoi 
    SET r.duplicateorder = 1; 

В общем, вам следует избегать курсоров, особенно тех, которые требуют динамического SQL. Когда вы можете выразить логику как заданную операцию, обычно это лучше всего сделать.

+0

Это сработало, как только я внес некоторые незначительные исправления (также, я дал неправильное имя таблицы, должен быть _orders): UPDATE _orders r JOIN (SELECT addressmatch, MIN (order_id) как minoi FROM _orders r2 WHERE orderdate> = (CURDATE() - INTERVAL 3 DAY) GROUP BY addressmatch ) dups ON r.addressmatch = dups.addressmatch и r.order_id> dups.minoi SET r.duplicateorder = 1; – rixter

1

ничего плохого с CONCAT, петля не инициировано/закрыто должным образом.

Этот set_dupe_loop: WHILE this_addr = match_addr

должен быть этот set_dupe_loop: WHILE this_addr = match_addr DO

Смежные вопросы