LINUX.ORG.RU

MySQL. выполнить UPDATE из IF()

 ,


0

1
CREATE EVENT `resource_167` ON SCHEDULE EVERY 1 SECOND DO BEGIN
UPDATE `towns2`
SET
`wood` = IF(`wood` + 250 / 3600 > 800, 800, `wood` + 250 / 3600),
`clay` = IF(`clay` + 100 / 3600 > 800, 800, `clay` + 100 / 3600), 
`iron` = IF(`iron` + 150 / 3600 > 800, 800, `iron` + 150 / 3600), 
`crop` = IF(`crop` + 200 / 3600 > 800, 800, `crop` + 200 / 3600), 
`Food` = IF(`Food` + (100 / 3600 - 150 / 3600) > 1000,
/* then */ 1000,
/* else */
IF(`Food` + (100 / 3600 - 150 / 3600) < 0, 0 /* желательно бы отсюда выполнить UPDATE, но чтобы IF все так же возвращал 0 */, `Food` + (100 / 3600 - 150 / 3600)) )
WHERE `wref` = 167; END

Сабж. Как? Заранее спасибо.

★★

Последнее исправление: Razip (всего исправлений: 1)

Ответ на: комментарий от Razip

Не совсем, разберись в чём разница между функцией, которая возвращает значение по условию и контролем исполнения по условию.

surefire ★★★
()
Ответ на: комментарий от surefire

The IF statement for stored programs implements a basic conditional construct.

В том, что конструкция IF доступна только в функциях?

Razip ★★
() автор топика
Ответ на: комментарий от someoneelsenotme

Короче, мне нужно UPDATE другой таблицы сделать.

Razip ★★
() автор топика
Ответ на: комментарий от KRoN73

Тогда не нужно что-то переписывать если нужно оперативно менять условия. Привычка после работы в техподдержке оракла:

WHERE 1=1
--  AND A
  AND B
  AND C
;

WHERE 1=1
  AND A
--  AND B
  AND C
;

WHERE 1=1
--  AND A
--  AND B
--  AND C
;
someoneelsenotme
()
Ответ на: комментарий от someoneelsenotme

Ну и плюс иногда в отчетах запросы генерятся и тогда можно тупо писать цикл генерации с маской 'AND XXX'

А тупо сделать join(' AND ', conditions);?

Оно к тому же и быстрее будет, конкатенация строк обычно более ресурсоёмкая операция (выделение/освобождение памяти на каждой операции), чем добавление строки в массив.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

А тупо сделать join(' AND ', conditions);?

Запросы могут генерироваться во внешний файл, который может где-то потом лежать. Намного проще написать:

printf("WHERE 1=1\n");
for (i = 0; i < 10; i++)
   printf("   AND column%d = 'yes'\n", %d);
printf(";\n");

Чем заниматься любовью с условиями или вставками в середину файла или массива.

someoneelsenotme
()
Ответ на: комментарий от someoneelsenotme

Намного проще написать
printf

Не... Это хорошо только для гарантированно одноразового случая. В львиной доле реальных задач со временем потребуется возвращать результат. И придётся вылавливать по всему коду printf'ы и менять на аггрегацию данных. Я на этих граблях плясал так много раз, что зарёкся выводить непосредственно на экран накапливаемые данные вообще :)

KRoN73 ★★★★★
()

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

Razip ★★
() автор топика
Ответ на: комментарий от Razip

Теперь у меня немного другой вопрос. Можно ли как-нибудь в строке с UPDATE заносить Food в переменную?

`Food` = IF(`Food` + (100 / 3600 - 150 / 3600) > 1000,
/* then */ 1000,
/* else */
IF(`Food` + (100 / 3600 - 150 / 3600) < 0, 0 /* желательно бы отсюда выполнить UPDATE, но чтобы IF все так же возвращал 0 */, `Food` + (100 / 3600 - 150 / 3600))
Конечно, можно наговнокодить - сначала делать UPDATE, потом SELECT новоиспеченной записи, условие, потом UPDATE другой таблицы, но не хочется если есть альтернативы. Если можно выделить в переменную, то я бы сделал условие, чтобы при food (переменная) == 0 выполнялся UPDATE другой таблицы.

Razip ★★
() автор топика
Последнее исправление: Razip (всего исправлений: 1)
Ответ на: комментарий от KRoN73

Не... Это хорошо только для гарантированно одноразового случая.

А вот все разработчики под Oracle с вами не согласны.

что зарёкся выводить непосредственно на экран

Суть не в принтфе, а в самом смысле кода.

someoneelsenotme
()
Ответ на: комментарий от Razip
DELIMITER !!

CREATE PROCEDURE `testing` () BEGIN
	SET @food = 0;

	UPDATE `testing` SET `food` = (@food := `food` + 1) WHERE `id` = 1;
    
    SELECT @food;
END

Решено.

Razip ★★
() автор топика
Ответ на: комментарий от someoneelsenotme

Суть не в принтфе, а в самом смысле кода.

Вот я про это не пишу. Не важно, printf, echo или out :) Важно, что обычно правильнее собирать готовый блок данных и возвращать (в т.ч. и на экран) его атомарно. А не печатать AND за AND'ом по одному :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Еще раз, если вам так удобнее воспринимать: возвращать можете атомарно, а чтобы сделать сам запрос вам придется в цикле его наращивать. И там удобнее не ставить где-то там условия, а просто сделать одинаковый шаблон для всех элементов цикла.

someoneelsenotme
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.