Oracle 合并到具有复合主键的表中

Oracle 合并到具有复合主键的表中,oracle,sql-merge,Oracle,Sql Merge,我试图在我的表中插入一些条目,但当条目已经存在时,我什么也不做。我的主键由多个列组成(事件\时间戳、设备\ id、路径、消息\ id) 当我在JDBC中尝试以下语句时: MERGE INTO events dest USING ( SELECT event_timestamp, device_id, path, message_id from events) src ON (dest.event_timestamp

我试图在我的表中插入一些条目,但当条目已经存在时,我什么也不做。我的主键由多个列组成(事件\时间戳、设备\ id、路径、消息\ 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 (?, ?, ?, ?, ?, ?, ?, ?, ?)
插入的所有内容都没有问题

我还尝试将select语句更改为select from
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


如何使其工作?

要传递的新值应该是
USING
子句中的
SELECT FROM dual
的一部分

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 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       = ?
      );

要传递的新值应该是
USING
子句中的
SELECT FROM dual
的一部分

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 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       = ?
      );

匹配后
尝试执行
更新
,这将确保匹配记录是否存在
事件\u时间戳
是日期还是时间戳列?如果是这样,请确保插入唯一的记录。@Jåcob:谢谢您的评论。当我尝试对任何引用的列
ORA-38104进行更新时,出现以下异常:on子句中引用的列无法更新
<代码>事件\时间戳
是一个时间戳列。我试图通过检查组合(事件时间戳、设备id、路径、消息id)来确保插入的记录是唯一的。如果您在Java中发布“普通”SQL,而不是字符串串联,那么在匹配时,您将更容易理解SQL,然后
尝试执行
更新
,这将确保匹配的记录确实存在或不存在。时间戳是日期还是时间戳列?如果是这样,请确保插入唯一的记录。@Jåcob:谢谢您的评论。当我尝试对任何引用的列
ORA-38104进行更新时,出现以下异常:on子句中引用的列无法更新
<代码>事件\时间戳
是一个时间戳列。我试图通过检查组合(事件\u时间戳、设备\u id、路径、消息\u id)来确保插入的是唯一的记录。如果在Java中发布“普通”SQL而不是字符串连接,那么理解SQL会更容易