#sql #oracle #plsql #sql-merge
#sql #Oracle #plsql #sql-слияние
Вопрос:
Я хочу вставить строку в таблицу, если ключей нет в таблице. Если ключи уже есть в таблице, я хочу обновить две временные метки в строке, как показано ниже:
Inputs to this routine include
lEarliest = TIMESTAMP
lLatest = TIMESTAMP
BEGIN
MERGE INTO mytable
USING dual ON (id1 = ? AND ...)
WHEN NOT MATCHED THEN
INSERT (...) VALUES (...)
WHEN MATCHED THEN
UPDATE SET earliest_timestamp = lEarliest where earliest_timestamp > lEarliest;
<--------- How can I add this second if statement to the Oracle MERGE clause? --------->
UPDATE SET latest_timestamp = lLatest where latest_timestamp < lLatest;
END;
/
Ответ №1:
...
when matched then update
set earliest_timestamp = least (earliest_timestamp, lEarliest),
latest_timestamp = greatest(latest_timestamp , lLatest)
where earliest_timestamp > lEarliest or latest_timestamp < lLatest
...
Таким образом, if, например, earliest_timestamp > lEarliest
но latest_timestamp >= lLatest
, earilest_timestamp
будет обновляться по желанию, в то время как latest_timestamp
будет обновляться до самого себя.
Это даже не «дополнительная работа», поскольку «дополнительная работа» вызвана целыми строками, которые должны быть обновлены (поэтому не стоит «обновлять» строку, в которой значение не изменилось); в этом случае обновляется вся строка, поскольку изменяется по крайней мере одно из значений.
Комментарии:
1. Спасибо @mathguy. Теперь это работает. Действительно хорошее и элегантное решение
2. Привет, GMB, я понял, что мне нужно обновить еще одну переменную при выполнении вышеупомянутого SQL. Я виноват, что не опубликовал это в первом экземпляре. Возможно ли решить проблему, упомянутую ниже? « НАЧАТЬ СЛИЯНИЕ В mytable, ИСПОЛЬЗУЯ dual ON (id1 = ? И …) ЕСЛИ ОНИ НЕ СОВПАДАЮТ, ТО ВСТАВЬТЕ (…) ЗНАЧЕНИЯ (…) ПРИ СОВПАДЕНИИ ЗАТЕМ ОБНОВИТЕ НАБОР earliest_timestamp = lEarliest, earliest_id = lEarliestId, где earliest_timestamp> lEarliest; ОБНОВИТЕ НАБОР latest_timestamp = lLatest, latest_id = lLatestId, где latest_timestamp < lLatest; END; / «