两个相同表结构之间的列值差异

时间:2013-11-15 19:57:10

标签: sql oracle

Oracle数据库:我有一个表与外部系统的数据保持同步。每隔15分钟,我们会获得此主表的任何更改。我们可以将此修改记录的源存储在临时表中。我们需要找到主表和登台表之间已更改的列,并记录这些差异以进行后续处理。

简单示例:

CREATE TABLE Master
(
 Id int NOT NULL,
 LastName varchar(255) NOT NULL,
 FirstName varchar(255),
 CONSTRAINT pk_ID PRIMARY KEY (Id)
);

现在,我有一个具有完全相同结构的Stage表。在这个简单的例子中,我可以在Master和Stage之间进行差异,如下所示:

  select decode( a.FirstName, b.FirstName, 0, 1 ) firstname_changed,
  decode( a.LastName, b.LastName, 0, 1 ) lastname_changed
  from Stage a, Master b
  where a.Id = b.Id;

现在的问题是主表包含145列。我想知道是否有更好的方法来做到这一点。

3 个答案:

答案 0 :(得分:0)

您可以在Oracle中使用Set Operations

UNION [ALL],INTERSECT,MINUS Operators

refer oracle doc link

答案 1 :(得分:0)

一种常见的方法是计算表的每一行的哈希值,作为插入或更新它的一部分(可能使用触发器)对要检测更改的所有列。在阅读新数据时也要这样做,你可以......

select t.id,
       case t.hash_value when s.hash_value then 'N' else 'Y' end changed
from   source_table s join target_table t on s.id = t.id.

这允许查询使用更小的哈希表作为连接的一部分。

答案 2 :(得分:0)

也许您可以将更改的行集加载到表中。然后将它们与现有表进行比较,只需更新整行。

Something like:
update <PermanentTable> p
(big giant column list)
as 
select <another big giant column list>
from <yourTempTable> t
where
t.<uniqueIdentifier = p.uniqueIdentifier

它仍然可以输入一大堆,但你可以保存脚本。

或许你可以做点什么

delete from <PermanentTable> p
inner join <yourTempTable> t
on p.uniqueid = t.uniqueid

然后只需插入登台表中的所有行。

或者也许你可以放弃整个手动CDC的东西,只是复制源表?