从另一个表更新表,但也插入

时间:2013-05-07 14:07:56

标签: sql oracle oracle10g

我们有一个源表,用于保存原始数据:

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

我正在尝试编写一个查询,该查询将处理每个产品的每一天源表中的数据,并将所有新行插入目标表,但我们还应将活动列更新为0 DEST。 table,如果在源中找到匹配的行(确定目标中是否存在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相同的OUTPUT。

还有其他方法可以实现这一目标。这不需要用MERGE来完成,我对任何其他解决方案都是开放的。

由于

2 个答案:

答案 0 :(得分:3)

你想做的是

  1. source中的所有记录插入destination
  2. destination.active
  3. 中的任何匹配记录更新source

    正如您正确指出的那样,您不能使用MERGE执行此操作,因为MERGE在找到匹配的记录而非更新和插入时希望进行更新。

    所以我认为你坚持做这两个陈述:更新destination 首先插入source的记录。

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

答案 1 :(得分:2)

为什么不运行2个查询?

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