Oracle內聯檢視更新遇到的問題.

壹頁書發表於2015-10-12

                      遇到一個批次更新的需求.
    我打算用內聯檢視更新+where in list的技巧處理

UPDATE ( 
    SELECT /*+ BYPASS_UJVC */ *
    FROM mvbox_space.music_original t1
        INNER JOIN (
            SELECT REGEXP_SUBSTR(value_str, '[^,]+', 1, 1) AS p1, REGEXP_SUBSTR(value_str, '[^,]+', 1, 2) AS p2
            FROM (
                SELECT SUBSTR(inlist, INSTR(inlist, ';', 1, LEVEL) + 1, INSTR(inlist, ';', 1, LEVEL + 1) - INSTR(inlist, ';', 1, LEVEL) - 1) AS value_str, level AS l
                FROM (
                    SELECT ';' || '20077,1;20078,2' || ';' AS inlist
                    FROM DUAL
                )
                CONNECT BY LEVEL <= LENGTH('20077,1;20078,2') - LENGTH(REPLACE('20077,1;20078,2', ';', NULL)) + 1
            )
        ) t2 ON t1.opus_id = t2.p1 
)
SET visit_num = nvl(visit_num, 0) + p2, total_today = nvl(total_today, 0) + p2, total_this_week = nvl(total_this_week, 0) + p2, total_this_month = nvl(total_this_month, 0) + p2

    在測試庫10.2.0.1透過.
    但是拿到線上10.2.0.4,居然報錯,這個內部的HINT沒有生效.
    後來改寫為

MERGE INTO mvbox_space.music_original t1 
USING (
    SELECT REGEXP_SUBSTR(value_str, '[^,]+', 1, 1) AS p1, REGEXP_SUBSTR(value_str, '[^,]+', 1, 2) AS p2
    FROM (
        SELECT SUBSTR(inlist, INSTR(inlist, ';', 1, LEVEL) + 1, INSTR(inlist, ';', 1, LEVEL + 1) - INSTR(inlist, ';', 1, LEVEL) - 1) AS value_str, LEVEL AS l
        FROM (
            SELECT ';' || '20077,1;20078,2' || ';' AS inlist
            FROM DUAL
        )
        CONNECT BY LEVEL <= LENGTH('20077,1;20078,2') - LENGTH(REPLACE('20077,1;20078,2', ';', NULL)) + 1
    )
) t2 ON t1.opus_id = t2.p1
WHEN MATCHED THEN UPDATE SET t1.visit_num = NVL(t1.visit_num, 0) + t2.p2, t1.total_today = NVL(t1.total_today, 0) + t2.p2, t1.total_this_week = NVL(t1.total_this_week, 0) + t2.p2, t1.total_this_month = NVL(t1.total_this_month, 0) + t2.p2


   
                    


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1813827/,如需轉載,請註明出處,否則將追究法律責任。

相關文章