SQL: обновить, если существует, иначе вставить ... но для нескольких строк с разными значениями - PullRequest
0 голосов
/ 18 марта 2011

Я хотел бы объединить вставку / обновление с оператором case, что означает, что я хочу вставить строку, если она не существует, обновить ее, если она существует, но в обоих случаях с разными значениями (при обновлении это зависит от идентификатора ) и при вставке, ну тогда я его установил ...

И это должно произойти в одном выражении SQL: -)

В двух словах: я пытаюсь объединить эти два утверждения в одно:

1). Вставка / Обновление:

MERGE INTO table_name USING dual ON (id='{id}')
WHEN MATCHED     THEN UPDATE SET {col1}='{val1}', {col2}={val2}
WHEN NOT MATCHED THEN INSERT ({id}, {col1}, {col2}) VALUES ('{id}', '{val1}', {val2})

2). Обновить разные значения с помощью регистра:

UPDATE SIGNALVALUE
    SET
        SIGNUMVALUE = CASE SIGID
        WHEN 49634 THEN 1.1
        WHEN 49674 THEN 2.2
        WHEN 49675 THEN 1.8
        END,
        UPDATETIME = CASE SIGID
        WHEN 49634 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        WHEN 49674 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        WHEN 49675 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        END
   WHERE SIGID IN (49634, 49674, 49675)

Эти заявления являются лишь примерами. На самом деле есть еще много строк для вставки / обновления, и это происходит часто, поэтому я пытаюсь минимизировать количество запросов.

Также я не могу выполнить обновление, а затем посмотреть, сколько строк было затронуто, а затем вставить те, которые не были исправлены, потому что я не буду знать идентификаторы строк, которые нужно вставить, по сравнению с теми, которые должны быть обновлены. По крайней мере, насколько я понимаю ... поправьте меня!

Ответы [ 2 ]

3 голосов
/ 18 марта 2011

Это не обязательно должна быть таблица в предложении using, вы также можете использовать SQL-запрос.
По крайней мере, это то, что вам нужно:)

merge 
 into target_table
using (select case when ... then ... else ... end as id
         from dual
      ) source_table
    on(target_table.id = source_table.id)
when matched then
   update 
      set ...
when not matched then
   insert (...)
   values (...)

Дайте мне знать, если это поможет.Если это так, я, вероятно, могу помочь написать окончательный запрос.

0 голосов
/ 18 марта 2011
MERGE INTO SIGNALVALUE USING (
SELECT 49674 as SIGID,
        TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
        '777' as SIGNUMVALUE
        FROM dual
        UNION ALL
SELECT 49675 as SIGID,
        TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
        '777' as SIGNUMVALUE
        FROM dual
        UNION ALL
SELECT 49676 as SIGID,
        TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
        '777' as SIGNUMVALUE
        FROM dual
) n
ON(SIGNALVALUE.SIGID = n.SIGID)
WHEN NOT MATCHED THEN
    INSERT (SIGID, SIGNUMVALUE, UPDATETIME) VALUES (n.SIGID, n.SIGNUMVALUE, n.UPDATETIME)
WHEN MATCHED THEN
    UPDATE SET SIGNUMVALUE=n.SIGNUMVALUE, UPDATETIME=n.UPDATETIME
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...