Вложенные циклы MySQL

12 3
sidorka
На сайте с 17.08.2012
Offline
211
2165

Признаюсь сразу - курсоры не осилил, так и не смог понять почему ошибку синтаксиса выдает.

Но скорость работы вот такого запроса вполне устраивает

SET @i:=0;

UPDATE table SET item1 = @i:=@i+item2 WHERE condition;

Но беда с ним, когда гоняю этот запрос во внешнем цикле, не обнуляется переменная @i - просто накапливается, как будто и нет никакого SET @i:=0.

LOOP:

Query("SET @i:=0;");
Query("UPDATE table SET item1 = @i:=@i+item2 WHERE condition;");
ENDLOOP;

ЧЯДНТ?

---------- Добавлено 04.11.2013 в 23:55 ----------

Сервер: Localhost via UNIX socket

Программа: MySQL

Версия программы: 5.5.34-0ubuntu0.13.04.1 - (Ubuntu)

Версия протокола: 10

Кодировка сервера: UTF-8 Unicode (utf8)

Дешевые домены для дорвеев и не только - от 55р (https://goo.gl/Wtnwqp)
sidorka
На сайте с 17.08.2012
Offline
211
#1

Осилил курсоры, но вопрос остался - это глюк в данной версии мускула или я как-то неправильно понимаю переменные? Самое интересное, что пробовал уникализировать имена переменных - рандомно цифры приклеивал - результат тот же, суммирование просто накапливается, как будто переменная одна и та же.

siv1987
На сайте с 02.04.2009
Offline
427
#2

Потому что переменная одна и та же

sidorka
На сайте с 17.08.2012
Offline
211
#3

Уточню, в мускуле на все про все только одна переменная, как ее не назови?

IL
На сайте с 20.04.2007
Offline
435
#4

А что ожидается получить в результате выполнения этой строчки:?

    Query("UPDATE table SET item1 = @i:=@i+item2 WHERE condition;");
... :) Облачные серверы от RegRu - промокод 3F85-3D10-806D-7224 ( http://levik.info/regru )
siv1987
На сайте с 02.04.2009
Offline
427
#5

Уточню, у вас а не в мускуле

sidorka
На сайте с 17.08.2012
Offline
211
#6
А что ожидается получить в результате выполнения этой строчки:?

Накопление переменной ожидается.

siv1987, уточню еще раз - я ее обнуляю в цикле. пробовал такой вариант:

LOOP:
$name = RANDOM;
Query("SET @$name:=0;");
Query("UPDATE table SET item1 = @$namei:=@$name+item2 WHERE condition;");
ENDLOOP;

Эффект тот же - она ведет себя как одна и та же переменная, причем обнулить себя не дает. Дело на пхп было, чтоб понятен код был - там такое допускается - запросы все равно как строки передаются в функции работы с мускулом.

---------- Добавлено 05.11.2013 в 21:16 ----------

Приведу и свое художество с курсорами - мож так понятней будет, что происходит. Это работает правильно.

DELIMITER $$
CREATE PROCEDURE `currr` ( ) BEGIN
DECLARE done INT DEFAULT 0;
DECLARE f_id INT;
DECLARE t_id INT;
DECLARE p INT;
DECLARE cur1 CURSOR FOR SELECT `from_id`, `to_id` FROM `links` WHERE 1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO f_id, t_id;
IF done THEN
LEAVE read_loop;
END IF;
SET p:= 0;
UPDATE `links` SET rng = @p:=@p + `freq` WHERE `from_id` = f_id AND `to_id` = t_id;
END LOOP;
CLOSE cur1;
END$$
DELIMITER ;
siv1987
На сайте с 02.04.2009
Offline
427
#7

Что то я не понимаю здесь роль этой переменной.

Если работает правильно тогда в чем проблема?

sidorka
На сайте с 17.08.2012
Offline
211
#8

Не работает правильно. Я в цикле меняю условия выборки - condition. Перед апдейтом пытаюсь обнулить переменную - мне нужно, чтобы по выборке сумма начинала накапливаться каждый раз с нуля. А переменная не обнуляется. Вот и подумал - в мускуле только одна переменная что ли?

---------- Добавлено 06.11.2013 в 01:36 ----------

По примеру с курсором видно, что должно выйти. Тут засада в том, что если не использовать встроенные возможности мускула, то при большом объеме БД это удовольствие растягивается надолго. А с таким подходом уже можно жить. С курсором еще лучше вышло.

A
На сайте с 19.07.2010
Offline
130
#9
sidorka:
Не работает правильно. Я в цикле меняю условия выборки - condition. Перед апдейтом пытаюсь обнулить переменную - мне нужно, чтобы по выборке сумма начинала накапливаться каждый раз с нуля. А переменная не обнуляется. Вот и подумал - в мускуле только одна переменная что ли?

посмотрите глазами вывод, есть ли двойные строки? двойные строки могут сбивать вашу переменную.

SELECT `from_id`, `to_id` FROM `links` WHERE 1;

ну или не глазами, как-то так, не проверял:

SELECT `from_id`, `to_id`, count(*) cc FROM `links`  group by from_id, to_id having cc>1

наверное нужно в курсор добавить distinct, чтобы исключить дупы "условий выборки":

DECLARE cur1 CURSOR FOR SELECT distinct `from_id`, `to_id` FROM `links`;
.............
sidorka
На сайте с 17.08.2012
Offline
211
#10

Курсор работает, не работает правильно апдейт, если гонять его внешним циклом. С курсором намного быстрее вышло. Просто разобраться хотелось с этим глюком.

12 3

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий