我目前正在编写更新语句,以使可查询表始终保持最新状态。两个表之间的模式相同,内容并不重要:
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”无效的标识符问题
答案 0 :(得分:33)
有两种方法可以做你正在尝试的事情
一个是Multi-column Correlated Update
UPDATE PRODUCTION a
SET (name, count) = (
SELECT name, count
FROM STAGING b
WHERE a.ID = b.ID);
您可以使用merge
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
答案 1 :(得分:2)
试试..
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
);
答案 2 :(得分:1)
如果没有分段数据集的例子,这是一个黑暗的镜头,但你尝试过这样的事情吗?
update PRODUCTION p,
staging s
set p.name = s.name
p.count = s.count
where p.id = s.id
假设id列在两个表上匹配,这将起作用。
答案 3 :(得分:0)
正如您所注意到的,您对更新语句没有选择性,因此它会更新整个表。如果要更新特定行(即ID匹配的位置),您可能希望执行协调的子查询。
但是,由于您使用的是Oracle,因此可能更容易为查询表创建实例化视图,并让Oracle的事务机制处理详细信息。 MV的工作方式与查询语义的表完全相同,设置起来非常简单,并允许您指定刷新间隔。