SQL - 从复杂查询更新Oracle 10g数据库

时间:2014-06-17 16:52:16

标签: sql oracle

尝试根据条件更新单个列。查询返回需要更新的行

SELECT 
it.objectid,
it.versionnumber,
it.itemnumber "Item Number", 
it.itemtype,
itcovprem.basisofsettlement,
itcovprem.coverage "Coverage"
FROM 
itemcoveragesandpremiums itcovprem,
items it,
policies pl
WHERE 
pl.objectid = it.parentobjectid AND 
pl.policytype in ('H','F') AND
it.objectid = itcovprem.itemobjectid AND
it.itemtype in ('SHOA','SHOB','SHOC','SHOD','SHOK','SHOL') and
it.versionnumber = itcovprem.itemversionnumber AND
((itcovprem.coverage like ('A - Dwg Bldg%')) or
(itcovprem.coverage like ('#42 - Repl Cost Plus%')) or
(itcovprem.coverage like ('#42 - Limited GRC%'))) and
it.effectivedate >= TO_DATE('01-JAN-2006', 'DD-MON-YYYY') and
exists (select * from itemcoveragesandpremiums icp where icp.itemobjectid = it.objectid and icp.itemversionnumber = it.versionnumber and icp.coverage like ('#42%')) and
itcovprem.basisofsettlement not in ('LGRC')

我已经尝试了一些选项将其转换为更新查询,但没有快乐。

我收到错误 - 第3行 - 使用

时SQL命令未正确结束
update itemcoveragesandpremiums
set basisofsettlement = 'LGRC'
from itemcoveragesandpremiums as itcovprem
inner join items as it
on it.objectid = itcovprem.itemobjectid and it.versionnumber = itcovprem.itemversionnumber
inner join policies as pl
on pl.objectid = it.parentobjectid 
where [cut, rest of query was below]

我得到错误 - 第6行 - 在尝试使用内联查询时缺少右括号

update
(
SELECT 
itcovprem.basisofsettlement as OLD
FROM 
itemcoveragesandpremiums as itcovprem inner join items as it on it.objectid = itcovprem.itemobjectid and it.versionnumber = itcovprem.itemversionnumber inner join policies AS pl on pl.objectid = it.parentobjectid 
WHERE [query snipped]
) t
set t.old = 'LGRC'

似乎SQL * Plus只是想在更新我的select查询之前停止查看更新。我不确定我是不正确地格式化它还是从错误的方向走向它。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

在您第一次尝试时,第3行的错误是因为update不支持fromjoin子句。在第二次尝试中,第6行的即时错误是因为您尝试使用as itcovprem对表进行别名;但是you can only use as for column aliases, not for table aliases。 (第一次尝试也试图这样做,但它没有达到遇到那个问题)。但是你通常不能用连接更新内联视图,所以它仍然会出错 - 就像ORA-01779。

您需要执行以下操作:

update itemcoveragesandpremiums
set basisofsettlement = 'LGRC'
where (itemobjectid, itemversionnumber, basisofsettlement, coverage) in (
  select it.objectid,
    it.versionnumber,
    itcovprem.basisofsettlement,
    itcovprem.coverage
  from ...
)

假设itemobjectid, itemversionnumber, basisofsettlement, coverage足够识别一行,这样您就不会冒任何风险更新。向选择中添加rowid并将其用于更新可能更安全,以避免歧义:

update itemcoveragesandpremiums
set basisofsettlement = 'LGRC'
where rowid in (
  select itcovprem.rowid as target_rowid
  from ...
)