Есть несколько способов. Самый простой из них - это использовать вычисления.
Рассмотрим на примере. Пусть в некоторой процедуре есть команда обновления остатка товара на складе:
UPDATE GOODS
SET ITEMS_COUNT = ITEMS_COUNT - V_SOLD_COUNT
WHERE ID = P_ID_GOOD;
После изменения остатка, если его новое значение стало меньше нуля, нужно выдать ошибку и откатить транзакцию (и ещё можно журналировать эту ошибку).
Итак, как получить новое значение строки, которое устанавливается в столбце ITEMS_COUNT в результате команды UPDATE для последующего его анализа.
MySql поддерживает разные типы переменных: с собачкой (@) и без этого предварительного символа. Первые переменные называются пользовательскими, а вторые - локальными. Ещё есть системные переменные (с двумя собачками), но о них в другой раз.
Пример присвоения значения пользовательской переменной (с собачкой):
SET @Var1 = 5;
Пример присвоения локальной переменной (без собачки):
SET var1 = 5;
Пользовательские переменные (с собачкой) можно использовать как очень мощный инструмент в SQL-командах. Например, присвоив значение переменной, можно тут же использовать его. Пример:
SELECT @var1 := 5 SOME_FIELD
FROM DUAL
В результате и в переменную запишется число 5 и можно сразу использовать значение переменной, например, чтобы вывести её командой SELECT (как в примере выше).
И нашу задачу, из-за которой я решил написать эту мини статью, это очень хорошо решает. Прямо в команде UPDATE мы запишем новое значение для строки в переменную и тут же используем её:
UPDATE GOODS
SET ITEMS_COUNT = @var1 := ITEMS_COUNT - V_SOLD_COUNT
WHERE ID = P_ID_GOOD;
Текущее значение строки за вычетом V_SOLD_COUNT будет присвоено переменной @var1 и её значение сразу же будет использовано для команды UPDATE.
И еще теперь переменную @var1 можно использовать и после команды UPDATE. Проверим установленное в строке значение и, если оно стало меньше нуля, откатим операции и выдадим ошибку.
UPDATE GOODS
SET ITEMS_COUNT = @var1 := ITEMS_COUNT - V_SOLD_COUNT
WHERE ID = P_ID_GOOD;
IF @var1 < 0 THEN
...
ROLLBACK;
SIGNAL ....;
ЛОГИРУЕМ ФАКТ ОШИБКИ;
END IF;
Использование переменной в команде UPDATE позволит запомнить новое значение строки и на основе него строить последующую логику (например, проверить на отрицательное значение). Только необходимо принимать во внимание наличие триггера на команду UPDATE уровня строки. Вдруг непосредственно перед установкой нового значения оно может быть подкорректировано триггером. Тогда лучше запоминать новое установленное значение прямо в триггере. Для справки: некоторые СУБД поддерживают опцию RETURNING DML команд, тогда финальное сохранённое значение в любом столбце можно получить и без вычислений, и не обращая внимание на наличие триггеров.
Подобные и другие задачи решаем на нашем онлайн интенсиве по разработке в MySql. Следующий поток уже в марте! Записывайся! Буду тебя ждать!
Поставь лайк, если понравилась, статья или подпишись!