Я хотел бы знать, возможно ли выполнить такое ОБНОВЛЕНИЕ в базе данных Oracle SQL:
UPDATE mark
SET
mark=
CASE
WHEN mark.val<= 5
THEN val*1.1
ELSE val END
WHERE mark.id_classes = classes.id_classes
AND classes.ID_subject = subject.ID_subject
AND subject.ID_subject = 5;
Разработчик SQL возвращает ошибку в этой части:
WHERE mark.id_classes = classes.id_classes
AND classes.ID_subject = subject.ID_subject
AND subject.ID_subject = 5;
Итак, я предполагаю, что невозможно создать такое сложное условие, есть ли другой способ сделать это?
Возможно, было бы глупо пробовать больше SELECT как условие, но с другой стороны, я не вижу причины, почему это не работает.


Вы не можете ссылаться на еще две таблицы (CLASSES и SUBJECT) Просто так из ниоткуда. Вот код, который показывает как, возможно, вы это сделали:
update mark m set
m.mark = (select case when m.val <= 5 then m.val * 1.1
else m.val
end
from classes c join subject s on c.id_subject = s.id_subject
where c.id_classes = m.id_classes
and s.id_subject = 5
)
where ...
Поскольку вы не использовали псевдонимы таблиц в CASE, я не знаю, к какой таблице принадлежит столбец VAL (поэтому я предположил, что это MARK).
Кроме того, самому UPDATE может понадобиться предложение WHERE, которое ограничит количество обновляемых строк.
Это установит mark на NULL, если нет совпадающих значений. Я не думаю, что это то, что имеет в виду ОП. Он также излишне обновляет строки.
О, теперь я понимаю, что вы имели в виду, право должно быть обновлено с помощью оператора if EXIST или sth.
Вот что означает ... позади WHERE.
Вы можете использовать подзапрос:
UPDATE mark
SET mark = val * 1.1
WHERE mark.val <= 5 AND
EXISTS (SELECT 1
FROM classes c JOIN
subjects s
ON c.ID_subject = s.ID_subject
WHERE mark.id_classes = c.id_classes AND
s.ID_subject = 5
);
Обратите внимание, что я переместил условие CASE в предложение WHERE, поэтому обновляются только те строки, которые необходимо обновить.
Тоже отлично работает, даже проще на мой взгляд большое спасибо.
Я считаю, что в подобных случаях оператор MERGE легче понять:
MERGE INTO MARK m
USING (SELECT c.ID_CLASSES
FROM CLASSES c
WHERE c.ID_SUBJECT = 5) d
ON (m.ID_CLASSES = d.ID_CLASSES)
WHEN MATCHED THEN
UPDATE SET m.MARK = CASE
WHEN m.VAL <= 5
THEN m.VAL * 1.1
ELSE
m.VAL
END
Или, поскольку ID_SUBJECT является константой, вы можете упростить обновление до
UPDATE MARK m
SET m.MARK = CASE
WHEN m.VAL <= 5
THEN m.VAL * 1.1
ELSE
m.VAL
END
WHERE m.ID_CLASSES = 5
Удачи.
Оцените другой подход :)
Да, это работает, спасибо за объяснение, в чем была проблема.