2

我们有一个保存原始数据的源表:

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。如果在源中找到匹配行(这取决于目标中是否存在 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 完成,我愿意接受任何其他解决方案。

谢谢

4

2 回答 2

4

你想做的是

  1. 将所有记录插入sourcedestination
  2. 更新destination.active任何匹配记录的列source

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

所以我认为你坚持这样做有两条语句:destination 先更新,然后从source.

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

于 2013-05-07T14:26:41.440 回答
2

为什么不运行 2 个查询?

 UPDATE DestinationTable
 SET Active = 0
 WHERE EXISTS (SELECT 1
               FROM SourceTable
               WHERE DestinationTable.Product = SourceTable.Product AND
                     DestinationTable.SD = SourceTable.SD)
于 2013-05-07T14:27:55.683 回答