2013-05-29 47 views
1

喜大師,我得到的錯誤ORA-01732:數據處理操作這種觀點不是法律執行下面的查詢剛開錯誤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'; 

我試圖優化第二查詢,由於第二查詢使用兩個選擇我試圖替換與一個查詢。任何人都可以幫助我嗎?

回答

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'; 
+0

感謝您的回答Chorel我對ROW_NUMBER()函數有疑問,函數將在ON條件滿足之後應用,或者將首先應用於內部查詢。 – user2433145

+0

條件'ORD_NO = 1'將應用於獲取數據集,然後使用'MERGE'的'ON'節中的條件將數據集匹配到CRS_T_CURRENT_RATES1。看看'MERGE'如何工作 - 鏈接到doc是由jonearles提供的。 – Chorel

+0

你能告訴我爲什麼你已經用'ORD_NO = 1'條件了嗎?如果我們刪除'ROW_NUMBER()'和'ORD_NO = 1',增加這個查詢有多不同? – user2433145

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 

更新

ROWNUMON子句中的作品更新的表,而不是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 

+0

不確定它是否能正常使用rownum。可能它只會與'USING'子句中的第一行合併。 – Chorel

+0

@Chorel它似乎工作,看我的更新。但是使用分析函數的想法很好,它可以幫助提高查詢的可讀性。 –

+0

對不起 - 我是對的,它不能正常工作:(http://sqlfiddle.com/#!4/7f35f/1/1)。請注意,只更新了一行。 – Chorel

相關問題