获取错误ORA-01732:此视图上的数据操作操作不合法

时间:2013-05-29 15:30:39

标签: oracle sql-update query-optimization

嗨大师我收到错误ORA-01732:数据操作操作在此视图上不合法

执行以下查询时

UPDATE (SELECT CR.AMOUNT AS AMOUNT,
                  CASE
                  WHEN MRG.AMOUNT_USD=0
                  THEN CR.AMOUNT
                  ELSE MRG.AMOUNT_USD
                  END AS AMOUNT_BILAT,
                  CR.ISUPDATED
                  FROM CRS_TT_BILAT_EXCL_MERGE1 MRG,CRS_T_CURRENT_RATES1 CR
                  WHERE SUBSTR(CR.DNIS_CD,1,3)=MRG.DNIS_CD
                  AND CR.PRODUCT_CUST_ID = MRG.PRODUCT_CUST_ID
                  AND CR.ISUPDATED <> 'Y'
                  AND ROWNUM = 1)
                  SET AMOUNT = AMOUNT_BILAT;
                  CR.ISUPDATED = 'Y';

我已从以下查询中简化了上述代码

UPDATE CRS_T_CURRENT_RATES1 CR
        SET CR.AMOUNT =
          (SELECT 
                  CASE
                  WHEN MRG.AMOUNT_USD=0
                  THEN CR.AMOUNT
                  ELSE MRG.AMOUNT_USD
                  END
                  FROM CRS_TT_BILAT_EXCL_MERGE1 MRG
                  WHERE SUBSTR(CR.DNIS_CD,1,3)=MRG.DNIS_CD
                  AND CR.PRODUCT_CUST_ID = MRG.PRODUCT_CUST_ID
                  AND ROWNUM = 1),

                  CR.ISUPDATED = 'Y'

           WHERE EXISTS
            (SELECT 1 FROM CRS_TT_BILAT_EXCL_MERGE1 MRG WHERE MRG.DNIS_CD = SUBSTR(CR.DNIS_CD, 1,3) AND CR.PRODUCT_CUST_ID = MRG.PRODUCT_CUST_ID )
            AND
            CR.ISUPDATED <> 'Y';

我正在尝试优化第二个查询,因为第二个查询使用了两个选项,我试图用单个查询替换它。任何人都可以帮我这个吗?

2 个答案:

答案 0 :(得分:1)

MERGE语句,为您的查询中的每个(AMOUNT_USD,DNIS_CD,PRODUCT_CUST_ID) - ROWNUM=1条件选择第一行:

MERGE INTO CRS_T_CURRENT_RATES1 CR
USING (SELECT * FROM (
          SELECT AMOUNT_USD, 
                 DNIS_CD, 
                 PRODUCT_CUST_ID
                 ROW_NUMBER() OVER (PARTITION BY AMOUNT_USD, DNIS_CD, PRODUCT_CUST_ID ORDER BY 1) AS ORD_NO
          FROM CRS_TT_BILAT_EXCL_MERGE1
          ) WHERE ORD_NO = 1
      ) MGR
ON CR.PRODUCT_CUST_ID = MRG.PRODUCT_CUST_ID AND
   SUBSTR(CR.DNIS_CD,1,3)=MRG.DNIS_CD 
WHEN MATCHED THEN
   UPDATE SET CR.AMOUNT = (CASE
                              WHEN MRG.AMOUNT_USD=0 THEN CR.AMOUNT
                              ELSE MRG.AMOUNT_USD
                          END),
                          ISUPDATED = 'Y'
   WHERE ISUPDATED <> 'Y';

答案 1 :(得分:0)

更新:使用MERGEROWNUM无效。

MERGE可以帮助您避免重复SQL:

MERGE INTO CRS_T_CURRENT_RATES1 CR
USING
(
    SELECT AMOUNT_USD, DNIS_CD, PRODUCT_CUST_ID
    FROM CRS_TT_BILAT_EXCL_MERGE1
)  MRG
    ON
    (
        SUBSTR(CR.DNIS_CD,1,3) = MRG.DNIS_CD
        AND CR.PRODUCT_CUST_ID = MRG.PRODUCT_CUST_ID
        AND ROWNUM = 1  
    )
WHEN MATCHED THEN UPDATE SET
    CR.ISUPDATED = 'Y',
    CR.AMOUNT = CASE WHEN MRG.AMOUNT_USD=0 THEN CR.AMOUNT ELSE MRG.AMOUNT_USD END

<强>更新

ROWNUM子句中的

ON适用于更新的表,而不适用于USING子句中的数据。下面的示例以两个相同的行开头,只有一个更新:

create table test1(a number, b number);
insert into test1 values(1, 1);
insert into test1 values(1, 1);

merge into test1
using
(
    select 1 a from dual
) test2
    on (test1.a = test2.a and rownum = 1)
when matched then update set b = 0;

select * from test1;

A  B
-  -
1  0
1  1