如何用数据列表更新数据库表

时间:2019-03-05 12:11:51

标签: sql oracle performance oracle12c

说我有一个包含两列的数据库表-vehiclelocation

每个vehicle有很多locations

当程序接收到包含每辆车位置列表的消息时,我可以执行以下任一操作:

  1. Delete车辆的所有位置并遍历消息以重新insert全部(效率低)
  2. Select从数据库中获取车辆的位置,遍历消息并创建一个列表,其中列出了数据库中但消息中没有的位置,以及消息中但数据库中没有的位置。删除(DELETE WHERE IN...)在数据库中但不在消息中的那些,insert在消息中但不在数据库中的那些。

这是我对SQL的了解使我失败的地方。有没有更有效的方法(即更少的SQL语句,更少的数据库时间,更少的锁定)来执行此操作(我无法执行存储过程)?

我的直觉告诉我,我必须能够做DELETE WHERE NOT IN...,才能省去选项2中的数据库select的麻烦-但是我仍然必须select才能知道还有哪些插入。是否有任何INSERT等效项-INSERT {THIS LIST OF locations} ALL WITH {this vehicle}?还是在这种情况下通常使用标准的同步逻辑?

1 个答案:

答案 0 :(得分:0)

比方说,您有V1AB位置的车辆XV2和{{1 }}。该消息用于位置为BQ的车辆V1

对于A部分,您可以使用:

Y

,对于deletedelete from t where veh = 'V1' and loc not in ('A', 'Y');

insert

位置merge保持不变,merge into t using (select 'V1' veh, 'A' loc from dual union all select 'V1' veh, 'Y' loc from dual) s on (t.veh = s.veh and t.loc = s.loc) when not matched then insert values (s.veh, s.loc); 删除了ABX添加了delete。如果表中有更多列,则可以在一个Y中完成整个操作,但是我不知道这样做是否会更快,因为这需要在源查询中进行联接。


编辑: 您必须以某种方式将“消息”构建为Oracle可读的数据结构。也许消息已经存储在某个表中,也许您可​​以使用临时结构。您没有在问题中指出这一点。 我为您提供了处理双重对象的示例,因为我必须以某种方式构造语句。对于mergemerge,您可以执行V1(A, B, C) 5次或使用较短的语法:

V3(X, Y)

union all是Oracle预定义类型,您也可以定义自己的(select 'V1' veh, column_value loc from table(sys.odcivarchar2list('A', 'B', 'C')) union all select 'V3' veh, column_value loc from table(sys.odcivarchar2list('X', 'Y')) )并使用它。

无论如何,每辆车都要运行sys.odcivarchar2list两次:

create type locations as table of varchar2(100)

delete一次:

delete from t where veh = `V1` and loc not in ('A', 'B', 'C');
delete from t where veh = `V3` and loc not in ('X', 'Y');