Объединить в таблицу с составным первичным ключом - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь вставить некоторые записи в свою таблицу и ничего не делать, когда запись уже существует.Мой первичный ключ состоит из нескольких столбцов (event_timestamp, device_id, path, message_id).

Когда я пытаюсь выполнить что-то вроде следующего утверждения в JDBC:

MERGE INTO events dest
                    USING ( SELECT event_timestamp, device_id, path, message_id from events) src
                    ON (dest.event_timestamp = src.event_timestamp
                    and dest.device_id = src.device_id
                    and dest.path = src.path
                    and dest.message_id = src.message_id)
                    WHEN NOT MATCHED THEN
                    INSERT (event_timestamp, device_id, path, message_id, text, direction, speed, net, gross)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)

Ничего не вставляется.

С нормальным оператором вроде:

INSERT (event_timestamp, device_id, path, message_id, text, direction, speed, net, gross) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)

все вставляется без проблем.

Я также попытался изменить оператор выбора для выбора из DUAL вместо таких событий, как:

MERGE INTO events dest
                    "USING ( SELECT event_timestamp, device_id, path, message_id from DUAL) src
                    ON (dest.event_timestamp = src.event_timestamp
                    and dest.device_id = src.device_id 
                    and dest.path = src.path
                    and dest.message_id = src.message_id)
                    WHEN NOT MATCHED THEN
                    INSERT (event_timestamp, device_id, path, message_id, text, direction, speed, net, gross)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)

Но тогда я получаю исключение: ORA-00904: invalid identifier

Что я могу сделать, чтобы это работало?

1 Ответ

0 голосов
/ 07 декабря 2018

Новые значения, которые вы хотите передать, должны быть частью SELECT FROM dual в предложении USING

MERGE INTO events dest USING (
     SELECT ? as event_timestamp,
            ? as device_id,
            ? as path,
            ? as message_id
     FROM dual
)
src ON (
      dest.event_timestamp = src.event_timestamp 
      AND dest.device_id = src.device_id 
      AND dest.path = src.path 
      AND dest.message_id = src.message_id
)
WHEN NOT MATCHED THEN INSERT (
     event_timestamp,
     device_id,
     path,
     message_id,
     text,
     direction,
     speed,
     net,
     gross ) VALUES (?,?,?,?,?,?,?,?,?);

Также может использоваться простой INSERT INTO .. SELECT, подобный этому.

INSERT INTO events (
     event_timestamp,
     device_id,
     path,
     message_id,
     text,
     direction,
     speed,
     net,
     gross ) 
SELECT ?,?,?,?,?,?,?,?,? FROM DUAL
WHERE NOT EXISTS ( select 1 from events d WHERE  
          d.event_timestamp  = ? 
      AND d.device_id        = ?
      AND d.path             = ?
      AND d.message_id       = ?
      );

Демо

...