是否可以使用select过滤某些要在表上合并的条目?
MERGE INTO (
SELECT * FROM P4PCA2_PIVOT_CA
WHERE ( CA_LIG_VTE_NUM_ID_PDT <> 0 )
) ta
USING P4DAS2_DONARTSTK tb ON (tb.NUM_ID_PDT =ta.CA_LIG_VTE_NUM_ID_PDT)
WHEN MATCHED THEN
UPDATE SET ta.COD_SECVTE_REVENT=tb.COD_SECVTE_REVENT);
答案 0 :(得分:5)
在Oracle中,您可以在(某些)视图或子查询上执行DML。指南是,如果Oracle能够从视图中检索物理行,则视图是可更新的。
因此,您可以在子查询上使用MERGE。在某些情况下这是有道理的。例如,假设您有一个包含状态列的表。您希望将新信息合并到此表中,但只修改具有STATUS='active'
的行。你可以写:
MERGE INTO (SELECT * FROM mytable WHERE status='active') old
USING (SELECT * FROM newtable) new
ON (new.id = old.id)
WHEN MATCHED THEN UPDATE SET old.data1=new.data1;
这似乎在9iR2中产生ORA-00903
。它的工作原理是11g。测试脚本:
create table t (id number, c varchar2(10));
insert into t (select rownum, 'aaa' from dual connect by level <= 1000);
merge into (select * from t where id <= 10) t
using (select 1 id from dual) d
ON (t.id = d.id)
when matched then update set c = 'iii';
答案 1 :(得分:0)
类似的东西:
MERGE INTO P4PCA2_PIVOT_CA ta
USING (
select tb.*
from P4DAS2_DONARTSTK tb
join P4PCA2_PIVOT_CA ta on tb.NUM_ID_PDT = ta.CA_LIG_VTE_NUM_ID_PDT
where ta.CA_LIG_VTE_NUM_ID_PDT <> 0
) t ON (t.NUM_ID_PDT =ta.CA_LIG_VTE_NUM_ID_PDT)
WHEN MATCHED THEN
update set ta.COD_SECVTE_REVENT=tb.COD_SECVTE_REVENT;
根据您的示例,我不确定USING
部分的加入是否正确。
基本思想是仅在USING子句中选择要更新的行,而不是INTO子句的一部分。
答案 2 :(得分:0)
11g以下版本的解决方法:
创建一个包来保存变量值:
CREATE PACKAGE PKG_MY_VARIABLES
as
CA_LIG_VTE_NUM_ID_PDT number;
end;
/
创建引用该包的视图。
create or replace view V_P4PCA2_PIVOT_CA
as
select *
from P4PCA2_PIVOT_CA
where CA_LIG_VTE_NUM_ID_PDT <> PKG_MY_VARIABLES.CA_LIG_VTE_NUM_ID_PDT ;
在运行merge语句之前,将package变量设置为您想要的值。
exec pkg_my_variables.CA_LIG_VTE_NUM_ID_PDT := 0;
对视图运行合并。
MERGE INTO V_P4PCA2_PIVOT_CA ta
USING P4DAS2_DONARTSTK tb ON (tb.NUM_ID_PDT =ta.CA_LIG_VTE_NUM_ID_PDT)
WHEN MATCHED THEN
UPDATE SET ta.COD_SECVTE_REVENT=tb.COD_SECVTE_REVENT);