Oracle:合并相当于全部插入



我已经在几个论坛上找到了答案,但没有成功,所以也许你可以帮我。我有一个INSERT ALL请求,它一次插入数千行。

INSERT ALL
INTO my_table (field_x, field_y, field_z) VALUES ('value_x1', 'value_y1', 'value_z1')
INTO my_table (field_x, field_y, field_z) VALUES ('value_x2', 'value_y2', 'value_z2')
...
INTO my_table (field_x, field_y, field_z) VALUES ('value_xn', 'value_yn', 'value_zn')
SELECT * FROM DUAL;

现在我想修改它,以便在满足某些条件时更新行。对于每一行,我可以有这样的东西:

MERGE INTO my_table m
USING (SELECT 'value_xi' x, 'value_yi' y, 'value_zi' z FROM DUAL) s
ON (m.field_x = s.x and m.field_y = s.y)
WHEN MATCHED THEN UPDATE SET 
field_z = s.z,
WHEN NOT MATCHED THE INSERT (field_x, field_y, field_z) 
VALUE(s.x, s.y, s.z);

有没有一种方法可以让我做一种"合并所有",将所有这些合并请求合并在一起?

或者我没有抓住要点,有更好的方法吗?

谢谢,

编辑:一个可能的解决方案是使用"UNIONALL"从对偶中选择一组,如下所示:

MERGE INTO my_table m
USING (
select '' as x, '' as y, '' as z from dual
union all select 'value_x1', 'value_y1', 'value_z1' from dual
union all select 'value_x2', 'value_y2', 'value_z2' from dual
[...]
union all select 'value_xn', 'value_yn', 'value_zn' from dual
) s
ON (m.field_x = s.x and m.field_y = s.y)
WHEN MATCHED THEN UPDATE SET 
field_z = s.z,
WHEN NOT MATCHED THEN INSERT (field_x, field_y, field_z) 
VALUES (s.x, s.y, s.z);

注意:我使用了第一个空行,以便在编写请求时能够以相同的格式生成所有行。我还在那里指定列名。

另一种解决方案是创建一个临时表,将所有数据插入其中,然后与目标表合并并删除临时表。

如果你从python脚本中传入数万行,我会这样做:

  1. 创建一个全局临时表(GTT-这是一个在会话级别保存数据的永久表(
  2. 获取python脚本,将行插入GTT
  3. 在Merge语句中使用GTT,例如:

merge into your_main_table tgt
using your_gtt src
on (<join conditions>)
when matched then
update ...
when not matched then
insert ...;

最新更新