2013-05-07 43 views
1

我们有一个源表,其中保存原始数据:从另一个表更新表,但也插入

SourceTable 
SD    Product P1 P2 
'01-Mar-2013' 'Prod1' 1 2 
'02-Mar-2013' 'Prod1' 3 4 
'03-Mar-2013' 'Prod1' 5 6 
'04-Mar-2013' 'Prod1' 7 8 
'04-Mar-2013' 'Prod2' 6 5 

,我们有目标表如下图所示:

DestinationTable 
SD    Product P1 P2 Active 
'01-Mar-2013' 'Prod1' 9 10 1 

我想编写一个查询,该查询将处理每个产品每天的源表中的数据,并将所有新行插入到目标表中,但我们还应该将dest中的Active列更新为0。表(如果在源中找到匹配行)(如果SD和Product列存在于目标中,则确定该表)。

处理数据后,destinationTable会应该是这样的:

SD    Product P1 P2 Active 
'01-Mar-2013' 'Prod1' 9 10 0 
'01-Mar-2013' 'Prod1' 1 2 1 
'02-Mar-2013' 'Prod1' 3 4 1 
'03-Mar-2013' 'Prod1' 5 6 1 
'04-Mar-2013' 'Prod1' 7 8 1 
'04-Mar-2013' 'Prod2' 6 5 1 

我试图用MERGE要做到这一点,但你不能更新,并在同一时间插入时有找到匹配。

MERGE DestinationTable AS d 
USING (SELECT SD, Product, P1, P2 FROM SourceTable) AS s ON d.Product = s.Product AND s.SD = d.SD 
WHEN MATCHED THEN UPDATE SET d.P1 = s.P1, 
         d.P2 = sdsP2 
         d.Active = 0 
WHEN NOT MATCHED THEN 
    INSERT(SD,Product, P1, P2, Active) 
    VALUES(s.SD, s.Product, s.P1, s.P2, 1); 

其实我已经做了什么,我想使用OUTPUT语句在SQL做然而,这是Oracle 10g和Oracle没有输出相同的SQL。

有没有其他的方法来实现这一点。这不必与MERGE一起完成,我可以为任何其他解决方案开放。

感谢

+0

ORACLE中的OUTPUT的等价物是RETURNING子句。不幸的是,MERGE不支持它。 – APC 2013-05-07 14:17:37

+0

谢谢,因为我已经更新了这个问题,这不一定要用Merge来完成。 – 03Usr 2013-05-07 14:20:55

回答

3

你想要做什么是

  1. 插入来自source所有记录到destination
  2. 更新destination.active列其中任何匹配记录source

由于你正确地指出,你不能用MERGE做到这一点,因为MERGE想要更新当它找到匹配的记录而不是更新和插入。

所以我认为你坚持做这两个报表:更新destination 首先然后插入source记录。

UPDATE和INSERT都支持RETURNING子句,它允许您为更新或插入的行收集标识符(和其他列)。它在文档中:find out more

2

为什么不运行2个查询?

UPDATE DestinationTable 
SET Active = 0 
WHERE EXISTS (SELECT 1 
       FROM SourceTable 
       WHERE DestinationTable.Product = SourceTable.Product AND 
        DestinationTable.SD = SourceTable.SD)