Oracle中不能用UPDATE FROM的解决方法

(此原文在我的百度空间里,原样搬运到新浪博客)

又是oracle!!

今天的业务需求是在SQL语句中完成一个更新,但所要的参数需要在另外2张表中查询,而且肯定不能抛到JAVA层用多次查询来完成。

最后的结果是:首先要连用2次 LEFT JOIN 构造一张表,然后做为子查询放到UPDATE语句中作为筛选条件。

要是SQL SERVER数据库,直接用update .....from.(子查询) on ....这样的语句就可以了。

今天鼓捣了半天,一直出不来,搜索了下,我X,原来ORACLE不支持 UPDATE.... FROM2011-03-10 <wbr>15:00 <wbr>Oracle中不能用UPDATE <wbr>FROM的解决方法

 

搜索到了2种解决方案。其中一种语句结构比较简单,以下是原文引用:

update (select a.sal asal,b.sal bsal,a.comm acomm,b.comm bcomm from emp a,emp1 b where a.empno = b.empno)
set asal = bsal,
acomm = bcomm;

这里的表是一个类视图。
当然你执行时可能会遇到如下错误:

ERROR 位于第 2 行:
ORA-01779: 无法修改与非键值保存表对应的列
这是因为新建的表emp1还没有主键的缘故

下面增加一个主键

alter table emp1
add constraint pk_emp1 primary key (empno);

执行之后

在执行前面的语句就能成功。

试了一会,果然行不通。我这次的情况是把子查询做为筛选,这个是把另一张实体表做为筛选条件。还是老实用另一种看上去麻烦的语句吧。2011-03-10 <wbr>15:00 <wbr>Oracle中不能用UPDATE <wbr>FROM的解决方法

语句结构是这样的:

Update emp
Set(sal,comm) = (select sal,comm. From emp1 where emp.empno = emp1.empno)
Where exists (select 1 from emp1 where emp1.empno = emp.empno)

最后那句Where exists (select 1 from emp1 where emp1.empno = emp.empno)完全没见过,管他的,试试呗。

最后成功的语句是:

UPDATE CUSTOMER.CONTRACT_ITEM_DETAIL CID
SET(M3_USEABLE,M3_USED) = (select TE.M3_USEABLE,TE.M3_USED FROM (
select PU.ORDER_ID,C.CONTRACT_ID CONTRACT_ID,C.MATKL MATKL,C.MAKTX,C.M3 M3,C.M3_USEABLE+OI.NUM M3_USEABLE,C.M3_USED-OI.NUM M3_USED,
        OI.NUM NUM FROM CUSTOMER.CONTRACT_ITEM_DETAIL c
                 LEFT JOIN CUSTOMER.PURCHASE_ORDER pu
                  ON PU.CONTRACT_ID = C.CONTRACT_NO
                 LEFT JOIN CUSTOMER.ORDER_ITEM OI
                  ON PU.ORDER_ID = OI.ORDER_ID AND OI.ORDER_ITEM_SAP_NO = C.MATKL 
    WHERE PU.ORDER_ID = 2321)TE WHERE CID.CONTRACT_ID = TE.CONTRACT_ID AND CID.MATKL = TE.MATKL)
Where exists (select 1 from (
select PU.ORDER_ID,C.CONTRACT_ID CONTRACT_ID,C.MATKL MATKL,C.MAKTX,C.M3 M3,C.M3_USEABLE+OI.NUM M3_USEABLE,C.M3_USED-OI.NUM M3_USED,
        OI.NUM NUM FROM CUSTOMER.CONTRACT_ITEM_DETAIL c
                 LEFT JOIN CUSTOMER.PURCHASE_ORDER pu
                  ON PU.CONTRACT_ID = C.CONTRACT_NO
                 LEFT JOIN CUSTOMER.ORDER_ITEM OI
                  ON PU.ORDER_ID = OI.ORDER_ID AND OI.ORDER_ITEM_SAP_NO = C.MATKL 
    WHERE PU.ORDER_ID = 2321)TE WHERE TE.CONTRACT_ID = CID.CONTRACT_ID AND TE.MATKL = CID.MATKL)

 

其中子查询TE表整个代码写了2次,使看上去比较复杂,其实很简单。。最后这个更新语句只需要输入订单号ORDER_ID 和物料号MATKL,以及输入月份在JAVA中把月份数字拼到M后面就可以了。放在这里做个保存吧,以后要是有需要可以查阅。

你可能感兴趣的:(oracle)