12

我目前正在编写更新语句以保持可查询表不断更新。两个表之间的架构是相同的,内容并不重要:

STAGING  

ID  
NAME  
COUNT    

PRODUCTION  

ID  
NAME  
COUNT

我的更新语句如下所示:

update PRODUCTION  
set name = (select stage.name from staging stage where stage.name=name  and rownum <2),  
    count =   (select stage.countfrom staging stage where stage.count=count  and rownum <2);

需要注意的两件事是 1)我的更新结束时没有 where 子句(这可能是问题所在)和 2)更新后的所有记录都具有相同的值。我的意思是:

BEFORE UPDATE:  

1,"JOHN", 12;  
2,"STEVE",15;  
3,"BETTY",2;  

AFTER UPDATE  

    1,"JOHN", 12;  
    2,"JOHN",12;  
    3,"JOHN",12;

我的问题是如何解决这个问题,以便表正确反映来自暂存的“新”数据作为正确的 SQL 更新?

更新

因此,我的暂存数据可能会巧合地反映其中的内容,PRODUCTION并且为了讨论,它将:

STAGING DATA TO MERGE:  

    1,"JOHN", 12;  
    2,"STEVE",15;  
    3,"BETTY",2; 

更新第二个

我想运行的查询是这样的:

update PRODUCTION
set production.name = staging.name,  
    production.count = staging.count

where production.name = staging.name;

然而,这会导致“staging.name”上出现无效标识符问题

4

4 回答 4

38

有两种方法可以做你正在尝试的事情

一个是多列相关更新

UPDATE PRODUCTION a
SET (name, count) = (
  SELECT name, count
  FROM STAGING b
  WHERE a.ID = b.ID);

演示

您可以使用合并

MERGE INTO PRODUCTION a
USING ( select id, name, count 
          from STAGING ) b
ON ( a.id = b.id )
WHEN MATCHED THEN 
UPDATE SET  a.name = b.name,
            a.count = b.count

演示

于 2012-07-27T18:33:15.947 回答
3

尝试一下 ..

UPDATE PRODUCTION a
SET (name, count) = (
SELECT name, count
        FROM STAGING b
        WHERE a.ID = b.ID)
WHERE EXISTS (SELECT 1
    FROM STAGING b
    WHERE a.ID=b.ID
 );
于 2015-12-29T07:11:28.823 回答
1

正如您所注意到的,您对更新语句没有选择性,因此它正在更新您的整个表。如果您想更新特定行(即 ID 匹配的位置),您可能需要执行协调子查询。

但是,由于您使用的是 Oracle,因此为查询表创建物化视图并让 Oracle 的事务机制处理细节可能更容易。MV 的工作方式与查询语义的表完全一样,非常容易设置,并允许您指定刷新间隔。

于 2012-07-27T17:42:33.640 回答
1

如果没有 staging 数据集的示例,这是在黑暗中拍摄,但是您是否尝试过类似的方法?

update PRODUCTION p,
       staging s
set p.name = s.name  
    p.count = s.count
where p.id = s.id

假设两个表上的 id 列都匹配,这将起作用。

于 2012-07-27T17:44:18.703 回答